Was ist XSS und wie schützt man sich?

Autor: Veröffentlicht

Kurz erklärt: XSS (Cross-Site Scripting) ist eine Sicherheitslücke, durch die der Browser nicht vertrauenswürdigen Code im Kontext der besuchten Website ausführt. Sie entsteht meist dann, wenn eine Anwendung Benutzerdaten als Bestandteil einer Seite oder als Code behandelt statt als einfachen Text. Entscheidend für den Schutz ist vor allem die sichere Ausgabe von Daten, nicht nur das Blockieren verdächtiger Eingaben.

Wie XSS funktioniert und was Angreifer tun können

Der Browser interpretiert HTML als Seitenstruktur und JavaScript als auszuführende Anweisungen. Fügt eine Anwendung ungeprüfte Inhalte an einer Stelle ein, an der sie als Code interpretiert werden, kann ein Angreifer das Verhalten der Seite bei anderen Benutzern beeinflussen. Solche Inhalte können aus einem Kommentar, einem Adressparameter, einem Profilnamen oder der Antwort eines externen Dienstes stammen.

Durch XSS ausgeführter Code läuft im Kontext der angegriffenen Website. Er kann zugängliche Daten auf der Seite auslesen, deren Inhalt verändern, ein gefälschtes Anmeldeformular anzeigen oder Aktionen mit den Berechtigungen des angemeldeten Benutzers ausführen. Die tatsächlichen Folgen hängen von den Funktionen der Anwendung und den eingesetzten Schutzmaßnahmen ab.

Das bedeutet nicht automatisch, dass der Server oder der gesamte Computer übernommen wird. Das Problem betrifft vor allem das Vertrauen des Browsers in Code, den die jeweilige Website ausführt. Benutzer können die richtige Adresse öffnen und trotzdem auf einer Seite mit schädlichen Inhalten landen.

Die drei am häufigsten beschriebenen Formen von XSS

Die Einteilung hilft festzustellen, woher die gefährlichen Inhalte stammen und an welcher Stelle die Anwendung sie verarbeitet:

Diese Begriffe schließen sich nicht immer gegenseitig aus. „Gespeichert“ und „reflektiert“ beschreiben hauptsächlich, auf welchem Weg die Daten eingebracht werden. „DOM-based“ bezeichnet dagegen den Ort der unsicheren Verarbeitung. Auch in einer Datenbank gespeicherte Inhalte können zu DOM-based XSS führen.

Einfaches Beispiel: Text wird als HTML behandelt

Angenommen, eine Anwendung zeigt einen Benutzernamen an. Führe das folgende Beispiel ausschließlich in deiner eigenen Testumgebung oder dort aus, wo du ausdrücklich dazu berechtigt bist:

const name = '<img src="x" onerror="alert(\'XSS-Test\')">';
const element = document.querySelector('#begruessung');
element.innerHTML = name;

Die Eigenschaft innerHTML weist den Browser an, den Wert als HTML zu interpretieren. Wird das Bild nicht geladen, kann die Fehlerbehandlung alert auslösen und damit ein Meldungsfenster anzeigen. Das demonstriert die Ausführung von Code, nicht den Diebstahl von Daten. Zusätzliche Schutzmaßnahmen des Browsers oder der Website können die Ausführung blockieren.

Soll der Name als einfacher Text erscheinen, ist dies die richtige Lösung:

const name = '<img src="x" onerror="alert(\'XSS-Test\')">';
const element = document.querySelector('#begruessung');
element.textContent = name;

Die Eigenschaft textContent zeigt die angegebene Zeichenfolge an, ohne ein Bild zu erzeugen oder die darin enthaltene Anweisung auszuführen. Der Unterschied ist grundlegend: Daten bleiben Daten. Man muss nicht erraten, welche Wörter oder Tags gefährlich sein könnten.

So schützt du eine Anwendung vor XSS

Stimme den Schutz darauf ab, wo die Daten verwendet werden. Bei der Ausgabekodierung werden Sonderzeichen so dargestellt, dass sie nicht als Syntax interpretiert werden. Für Text in HTML gelten andere Regeln als für einen Attributwert, eine URL oder einen Abschnitt mit JavaScript. Nur die spitzen Klammern < und > zu ersetzen, schützt nicht in all diesen Situationen.

Verwende für die Ausgabe von einfachem Text sichere Template-Mechanismen und Schnittstellen wie textContent. Die automatische Kodierung eines Frameworks hilft, lässt sich aber durch eine Funktion umgehen, die unverarbeitetes HTML einfügt. Solche Ausnahmen müssen gesondert geprüft werden.

Wenn Benutzer tatsächlich Formatierungen mit HTML benötigen, verwende eine aktiv gepflegte Bibliothek zur Bereinigung, etwa DOMPurify. Diese Bereinigung, auch Sanitization genannt, entfernt unzulässige Elemente und Attribute nach festgelegten Regeln. Ein selbst gebauter Filter mit einigen regulären Ausdrücken bietet keinen gleichwertigen Schutz.

Validierung, also die Prüfung auf ein zulässiges Datenformat, bleibt sinnvoll: Ein Altersfeld sollte eine Zahl akzeptieren, eine Linkadresse ein erlaubtes URL-Schema verwenden. Sie ersetzt jedoch nicht die sichere Ausgabe. Auch nur das Formular abzusichern reicht nicht aus, denn Daten können auf anderen Wegen in die Anwendung gelangen.

Zusätzliche Schutzschichten begrenzen die Folgen von Fehlern. Mit CSP (Content Security Policy) lassen sich Regeln für die Ausführung von Skripten festlegen. Ihre Wirksamkeit hängt jedoch von der Konfiguration ab. Das Attribut HttpOnly verhindert, dass JavaScript ein Cookie ausliest. Es verhindert aber nicht jede Aktion, die schädlicher Code innerhalb einer aktiven Sitzung ausführen kann.

So beginnst du mit der Prüfung deiner eigenen Website

Verfolge die Daten eines einzelnen Feldes von der Eingabe bis zu jeder Stelle, an der sie angezeigt werden. Ein Kommentar kann unter einem Artikel sicher ausgegeben werden, im Moderationsbereich oder in der Vorschau einer Benachrichtigung dagegen unsicher. Prüfe außerdem die Verwendung von innerHTML und von Funktionen, mit denen sich die automatische Kodierung umgehen lässt.

Teste anschließend in einer isolierten Umgebung, ob der eingegebene Inhalt als Text erscheint oder die Seitenstruktur verändert. Ergänze nach der Korrektur einen Regressionstest, der erkennt, wenn diese Daten erneut als HTML behandelt werden.

Siehe auch: Was ist 2FA?

Lesen Sie auch

Wie PHP-FPM PHP-Anfragen verarbeitet, sich vom Webserver unterscheidet und wie du Prozesse an Last und Hosting-Ressourcen anpasst.
BIND ist offene DNS-Serversoftware. Erfahre, welche Aufgaben sie übernimmt und wann sich der Betrieb eines eigenen Servers lohnt.
Was Polens REGON-Register und seine Kennnummer bedeuten, wie sie sich von NIP und KRS unterscheiden und wie Sie Unternehmensdaten prüfen.