Cross-Site Scripting erklärt
Was ist ein XSS-Angriff?
Foto: vectorwin - shutterstock.com
Bei einer Cross-Site-Scripting-Attacke injiziert ein Angreifer bösartigen Code in Webformulare oder URLs. Dieser Code, für gewöhnlich in JavaScript oder PHP geschrieben, kann viele Formen von Unheil anrichten - von der Zerstörung der Website, die Sie zu laden versuchen, bis hin zum Diebstahl Ihrer Kennwörter oder anderer Anmeldedaten.
Cross-Site Scripting - Funktionsweise
Jeder kann eine Website einrichten, die bösartigen Code enthält. Bei einem Cross-Site-Scripting-Angriff richtet ein Angreifer die Dinge so ein, dass sein Code auf den Computer des Opfers gelangt, sobald dieser auf die Webseite eines Dritten zugreift. Das wird im Rahmen von Cross-Site-Scripting-Angriffen ohne privilegierten Zugang zum Webserver bewerkstelligt. Stattdessen machen sich die Angreifer zunutze, wie moderne Webseiten funktionieren.
Wollte man das Web grundlegend erklären, könnte sich das ungefähr so lesen: Wer eine Webseite erstellen möchte, schreibt ein HTML-Dokument und lädt es auf einen Webserver hoch. Möchte ein Benutzer auf diese Seite zugreifen, steuert er mit seinem Browser die Adresse des Servers an. Sein Browser lädt dann den HTML-Code herunter und interpretiert ihn, um eine Version der Webseite für den Benutzer zu erstellen.
Diese Beschreibung ist zwar nicht komplett falsch, dennoch sind einige Aspekte veraltet. Zunächst einmal sind viele, wenn nicht sogar alle Webseiten heutzutage dynamisch: Sie zeigen nicht jedem Besucher denselben statischen HTML-Code an, sondern werden bei einer Browser-Anforderung individuell aus den Informationen der Serverdatenbank erstellt. Welche Seite der Browser vom Server "zurückerhält", hängt oft von den Informationen ab, die er mit seiner Anfrage sendet. Diese nehmen manchmal die Form von URL-Parametern an. Zudem bestehen Websites nicht nur aus HTML und Cascading Style Sheets (CSS), die beschreiben, wie Text und Grafiken gerendert werden sollen. Sie enthalten auch ausführbaren Code, der in Skriptsprachen geschrieben ist, in der Regel JavaScript. Daten, grafische Darstellung und ausführbaren Code auf diese Art und Weise zu vermischen, stellt quasi eine "Erbsünde" der Web-Sicherheit dar.
Bei einem XSS-Angriff nutzt ein krimineller Hacker die Interaktion zwischen Benutzer und Website aus, um bösartigen Code auf dem Computer des Users auszuführen. Das funktioniert folgendermaßen:
https://www.google.com/search?q=CSO+online
Geben Sie diese Adresse in die Adressleiste Ihres Browsers ein, sehen Sie die Google-Suchergebnisse für "CSO Online". Die Seite, die Sie sehen, sieht genau so aus, als hätten Sie "CSO Online" in die Google-Suchleiste eingegeben. Die Probleme beginnen, wenn diese URL nun anstelle des unschuldigen Begriffs "CSO online" bösartigen JavaScript-Code enthält:
https://www.google.com/search?<script>doEvil()</script>
"doEvil()" steht hier stellvertretend für eine bösartige Funktion. Dass es im Fall von Google dazu kommt, dass tatsächlich bösartiger Code auf diese Art und Weise ausgeführt wird, ist höchst unwahrscheinlich. Der Suchmaschinenriese hat diverse talentierte IT-Sicherheitsprofis zur Verfügung, die entsprechende Maßnahmen ergreifen, um das zu verhindern (dazu später mehr). Dass das passiert, ist aber nicht bei jeder Webseite selbstverständlich.
Cross-Site Scripting - Angriffskategorien
Cross-Site-Scripting-Angriffe lassen sich in verschiedene Kategorien einteilen:
Nicht-persistente Angriffe: Das eben beschriebene Beispiel ist eine Reflected Attack beziehungsweise ein nicht-persistenter Angriff, da das bösartige JavaScript vom Webbrowser des Opfers an Google gesendet und dann in ausführbarer Form zurückgesendet wird, ohne dauerhaft auf den Google-Servern gespeichert zu werden. Reflected Attacks sind oft Teil von Phishing-Kampagnen.
DOM-basierte Angriffe: Diese XSS-Variante ist nach dem Document Object Model benannt, einer standardisierten API, die definiert, wie Browser eine Webseite aus dem zugrundeliegenden HTML- oder JavaScript-Code aufbauen. Die meisten DOM-basierten Angriffe ähneln den soeben beschriebenen nicht-persistenten Angriffen - mit dem Unterschied, dass der bösartige Code nie an den Server gesendet wird. Stattdessen wird er als Parameter an eine JavaScript-Funktion übergeben, die im Browser selbst ausgeführt wird. Das bedeutet auch, dass serverseitige Abwehrmaßnahmen den Benutzer nicht schützen können. Einen ausführlicheren Einblick in die Funktionsweise von DOM-basierten Angriffen bietet etwa PortSwigger.
Persistente Angriffe: Die dritte Hauptkategorie von Cross-Scripting-Angriffen sind persistente Angriffe oder Stored Attacks. Bei dieser Angriffsart gelingt es dem Angreifer, die interaktiven Funktionen einer Website zu nutzen, um einen bösartigen Code auf dem Webserver zu speichern. Ein gängiges Beispiel: Ein Angreifer hinterlässt einen Kommentar zu einem Blogbeitrag, der bösartiges JavaScript enthält. Wenn die Seite das nächste Mal aufgerufen wird, wird der Code ausgeführt.
XSS - Schwachstellen und Payloads
Eine Webanwendung ist anfällig für XSS-Angriffe wenn:
sie auf naive Weise Benutzereingaben entgegennimmt,
diese nicht auf potenziell bösartigen Code überprüft und
den Input beispielsweise verwendet, um eine Webseite zu rendern.
Dabei steht viel auf dem Spiel: Ein wichtiger Aspekt der Browser-Sicherheit ist die so genannte Same-Origin-Policy, die besagt, dass ein Skript, das auf einer Seite ausgeführt wird, nur dann auf Daten auf einer zweiten Seite zugreifen kann, wenn die beiden Seiten einen gemeinsamen Ursprung haben (definiert als Kombination aus URI-Schema, Hostname und Portnummer). Wenn jedoch ein bösartiges JavaScript im Browser ausgeführt werden kann, während das Opfer auf eine Website zugreift, ermöglicht der Browser diesem JavaScript den Zugriff auf Daten von anderen Seiten, die einen gemeinsamen Ursprung mit der anfälligen Seite haben. Dieses JavaScript kann auf Cookies und andere eingeschränkte Sitzungsinformationen zugreifen - für Cyberkriminelle ein gutes Rezept, um die Online-Konten ihrer Opfer zu kompromittieren.
Im Malware-Jargon ist ein Payload ausführbarer Code, der die vom Angreifer gewünschten Aktionen ausführt. Bei einem XSS-Angriff ist der Payload der Skriptcode, den der Angreifer im Browser des Opfers zum Laufen bringt. Das payloadbox-Repository auf GitHub enthält eine umfangreiche Liste von Beispielen für Cross-Site-Scripting-Payloads. Dabei gehört zu einem XSS-Angriff weit mehr, als nur einen Payload per Copy und Paste in die URL einzufügen. Angreifer müssen die spezifischen Funktionen und Schwachstellen der Webanwendung, die sie angreifen wollen, kennen. Die OWASP Foundation bietet auf ihren Seiten einen Deep Dive zum Thema.
Ein wichtiger Aspekt, um Ihre Webanwendung sicher zu halten: Das Testen auf XSS-Schwachstellen. Auch an dieser Stelle bietet OWASP hilfreiche Ressourcen, die detailliert beschreiben, wie Sie Ihre Anwendungen auf Anfälligkeiten für DOM-basierte oder nicht-persistente Cross-Site-Scripting-Angriffe testen können. Darüber hinaus steht Ihnen an gleicher Stelle auch ein Cheat Sheet zur Verfügung, das XSS-Attacken unter die Lupe nimmt, die bestimmte Abwehrfilter umgehen können.
Cross-Site Scripting - Präventionsmaßnahmen
Wenn Sie eine Webanwendung oder eine interaktive Website erstellen oder betreiben, sollten Sie drei wesentliche Funktionen integrieren, um potenzielle Cross-Site-Scripting-Angriffe abzuschwächen.
Input Sanitization: Um zu verhindern, dass bösartiger Skriptcode an den Benutzer weitergegeben wird, besteht die offensichtliche Antwort darin, Skriptcode gar nicht erst als Eingabe zu akzeptieren. Zumindest sollten Sie die Eingaben in diesem Sinne filtern. Das ist jedoch leichter gesagt als getan - geschickt gestaltete Code-Schnipsel lassen sich auch durch diese Filter schleusen. Um damit umzugehen, eignet sich der Whitelist- besser als der Blacklist-Ansatz: Statt einen Filter zu schreiben, der bösartigen Code in einem Webformular blockiert, sollten Sie Ihre Anwendung so schreiben, dass sie nur Daten in bestimmten Formaten (Telefonnummern, E-Mail-Adressen etc.) akzeptiert.
Output Escaping: Wenn Ihre Webanwendung vom Benutzer eingegebene Daten an eine Webseite zurücksendet, sollten diese Daten gefiltert werden, um sicherzustellen, dass sie nicht zu ausführbarem Code auf dieser Webseite werden. Wenn der Benutzer HTML-Tags als Code eingibt, sollte Ihre Anwendung Escape-Zeichen verwenden, um sicherzustellen, dass diese Tags als Text auf der resultierenden Seite erscheinen und nicht in den HTML-Code der Seite selbst integriert werden.
Content Security Policy (CSP): CSP erweitert den Whitelist-Ansatz über den reinen Eingabetext hinaus auf die Ausführung von Skripten: Ihre Webanwendung sollte nur den Code ausführen, den Sie als sicher eingestuft haben. Google hat einige ausgiebige Ressourcen zur Implementierung von CSP. (fm)
Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation CSO Online.