vuln-class-xss
Cross-Site Scripting (XSS), verständlich erklärt
XSS erlaubt Angreifern, eigenes JavaScript in der Browser-Sitzung einer anderen Person auf Ihrer Seite auszuführen. Die Folgen: Account-Übernahme, gestohlene Passwörter, gefälschte Login-Masken.
Worum es geht
Cross-Site Scripting (XSS) ist eine Bug-Kategorie, bei der ein vom Angreifer kontrollierter Text so auf Ihrer Seite landet, dass der Browser ihn als Code statt als Inhalt interpretiert. Aus dem Text wird JavaScript, das im Browser einer Besucherin innerhalb Ihrer Origin läuft. Aus deren Sicht ist der Code Teil Ihrer Seite, gleiche Domain in der Adresszeile, gleiches Schloss-Symbol. Der Angreifer kann alles, was die eingeloggte Sitzung der Person darf.
Der zugrundeliegende Fehler ist immer derselbe: Eine Eingabe ist hereingekommen und wurde so in die Seite geschrieben, dass sie für den Ort, an dem sie landete, nicht passend behandelt wurde. Die Varianten unterscheiden sich nur darin, woher die Eingabe kommt.
Drei Varianten
Reflected XSS
Der Angreifer baut eine URL mit dem Schad-Payload, schickt sie der Zielperson (Mail, Chat, Werbung), und die Anwendung gibt das Payload in der Antwort zurück. Klassische Quellen: Suchformulare, Fehlermeldungen. Reichweite: ein Opfer pro Klick, für gezieltes Phishing reicht das.
Stored XSS
Das Payload wird in die Datenbank geschrieben und an alle ausgeliefert, die die betroffene Seite anschauen. Forenbeiträge, Kommentare, Benutzernamen, Profilbeschreibungen, Support-Tickets, Produkt-Reviews: jedes Feld, in das eine Person Text tippt, der später bei anderen ankommt. Ein Angriff, viele Opfer.
DOM-based XSS
Der Bug liegt rein im Frontend-Code: eine JavaScript-Datei in der
Seite liest angreifer-kontrollierte Eingaben (location.hash,
postMessage, der URL-Query-String) und fügt sie so ins DOM ein,
dass Skript ausgeführt wird. Ihr Server kann komplett unschuldig
sein, der Bug lebt im Client-Code.
Warum das wichtig ist
XSS verschafft dem Angreifer im Moment der Ausführung die Sitzung der Besucherin. Konkret:
- Account-Übernahme. Jeder Cookie ohne ausdrücklichen JavaScript-Schutz ist lesbar. Selbst Cookies mit solchem Schutz reichen nicht: das Skript kann einfach im Namen der Person Requests innerhalb der offenen Sitzung absenden.
- Diebstahl von Formulardaten. Jedes Submit-Event abfangen, Passwort, Zahlungsdetails oder Nachricht abgreifen, bevor das Formular Ihren Server erreicht.
- In-Place-Phishing. Den Seiteninhalt durch eine gefälschte
Login-Maske ersetzen, die wie die echte aussieht. Adressleiste:
ihre-domain.de. Schloss: grün. - Wurm-artige Verbreitung. Bei Stored-XSS in einer Social-Funktion postet das Payload sich überall hin, wo die Zielperson Zugriff hat (wie damals der Samy-Wurm auf MySpace oder die Twitter-Retweet-Würmer).
In einem CMS oder Admin-Panel bedeutet XSS in der Sitzung einer Admin-Person praktisch volle administrative Kontrolle über die Seite.
Wie das behoben wird
XSS wird durch Kontext-passendes Encoding der Ausgabe behoben, nicht durch Filtern der Eingabe. Derselbe String ist an einer Stelle sicher, an einer anderen gefährlich.
| Ausgabe-Kontext | Was zu tun ist |
|---|---|
| HTML-Bodytext | <, >, &, ", ' durch HTML-sichere Entsprechungen ersetzen |
| HTML-Attributwert | HTML-encoden und Attribut quoten |
| JavaScript-Stringliteral | JS-escapen, besser JSON-encoden |
| URL-Parameter | URL-encoden |
| CSS-Kontext | Vermeiden; wenn unvermeidlich, strikte Allowlist |
In der Praxis machen moderne Frameworks das Richtige per Default:
- React, Vue, Svelte, Angular escapen Text in Templates
automatisch. Die gefährlichen Funktionen heißen explizit
(
dangerouslySetInnerHTML,v-html,[innerHTML]); Audits finden sie. - Template-Engines (Jinja, Twig, ERB, Liquid) escapen per
Default; das riskante Pendant heißt
{{ raw }}/safe/ ähnlich. - Backend-Code, der HTML von Hand baut, ist die riskanteste
Stelle; jedes
out.write("<div>" + x + "</div>")wartet auf den passenden Input.
Zusätzliche Schichten als Auffangnetz, falls das Encoding einmal versagt:
- Eine Content Security Policy mit Nonces oder Hashes (siehe unseren CSP-Artikel). Mit CSP tut sich ein erfolgreiches XSS-Payload schwer, angreifer-kontrollierte Skripte nachzuladen, an angreifer-kontrollierte Hosts zu exfiltrieren oder neue iframes zu öffnen. Verhindert XSS nicht, deckelt aber den Schaden.
- HttpOnly-, Secure- und SameSite-Attribute auf Session-Cookies. Ein Session-Cookie mit diesen Attributen ist für JavaScript nicht lesbar und wird in den meisten Fällen nicht bei Cross-Site-Requests mitgeschickt. Heilt XSS nicht, reduziert aber den Hebel.
Wie blueredix XSS meldet
Der Scanner injiziert keine XSS-Payloads aktiv in Ihre Live-Anwendung. Das ist autorisierten Tests vorbehalten. Was wir melden:
- CVEs in Drittanbieter-Software (Admin-Panels, CMSs, Plugins), deren Beschreibung XSS nennt.
- JavaScript-Bibliotheken mit dokumentierten XSS-Schwachstellen und verfügbarer Fix-Version.
- Header-Anzeichen: fehlendes
Content-Security-Policy, fehlendesX-Content-Type-Options: nosniff, Cookies ohneHttpOnly. Jedes davon erleichtert die Ausnutzung von XSS.
Ein echter Test gegen die XSS-Resilienz Ihres eigenen Codes ist ein manueller Review oder Penetrationstest, kein automatisierter Black-Box-Scan.