Cross-Site-Scripting ist wohl eine der bekanntesten Angriffstechniken bei Webanwendungen, und inzwischen ein Klassiker, der immer noch viel Potential für Hacker bietet. Auf Platz 7 der OWASP Top-10 ist XSS eine Technik bei der Angreifer Schadcode auf Webseiten einschleusen kann, der dann bei ihren Opfern im Browser ausgeführt wird, um Daten zu manipulieren, zu stehlen, oder Aktionen im Namen der Opfer auszuführen.

Übersicht

XSS ist so alt wie das WWW selbst. Seitdem es Browser und JavaScript gibt, gibt es auch die Möglichkeit, Schadcode auf einer Webseite zu platzieren. Wenn dann ein Opfer die Webseite aufruft, lädt auch dieser Schadcode und wird vom Browser ausgeführt. Schadcode ist in der Regel JavaScript, und JavaScript wird vom Interpreter des Browsers ausgeführt. Je nach dem, was der Browser alles zulässt bzw. nicht verhindert, können entsprechend kritische Dinge getan werden. Im Lauf der Zeit sind die Browser hier immer restriktiver geworden, so dass per JS nicht mehr so viel Schaden angerichtet werden kann. Die modernen Browser führen bei Webseiten die Skripte in einer Sandbox aus, aus der nicht ohne Weiteres ausgebrochen werden kann. Aber innerhalb der Webseite kann immer noch viel Schaden angerichtet werden, wenn man als Entwickler von Webanwendungen nicht aufpasst. Zum Glück gibt’s da inzwischen sehr effektive Präventionsmaßnahmen. Wenn man diese kennt und beachtet, hat man dieses Risiko auch im Griff. Wenn nicht, dann setzt man seine Besucher großen Gefahren aus.

Das Prinzip von XSS 

Was kann ein Angreifer mit XSS tun?

Ein Klassiker ist für Angreifer das Kapern einer bestehenden Browser-Session, denn wenn man die Session-ID kennt, dann dringt man in eine authentifizierte Sitzung ein, und hat so alle Rechte des Opfers und kann alles tun, was er tun kann.

Wir wollen uns also anschauen, wie so etwas ablaufen kann:

  1. Zur Vorbereitung postet der Angreifer eine Nachricht mit XSS-Schadcode z.B. auf einer Produkt-Webseite, z.B. in Form von Benutzer-Feedback oder Rezension.
  2. Ein anderer Benutzer will diese Webseite nun anzeigen, macht einen Http-Request indem er diese Webseite besucht.
  3. Der Server erzeugt daraufhin eine Session und zeigt die Seite an – liefert einen Http-Response, der die Nachricht vom Angreifer enthält mit dem XSS-Schadcode.
  4. XSS-Schadcode wird beim Benutzer ausgeführt und kann jetzt auf die Inhalte der Webseite zugreifen. Also auf alle Daten die der Browser darstellt und auch auf seine Cookies, falls die nicht gesondert geschützt sind. Um die Session-ID zu stehlen, kann der Angreifer jetzt auf das Session-Cookie zugreifen und die Session-ID auslesen. Diese kann er dann mit einem JS-Befehl an einen anderen Webserver schicken, nämlich an seinen eigenen, den er zuvor nur für diesen Zweck eingerichtet hat. 
  5. Mit dieser Session-ID ausgestattet besucht der Angreifer jetzt dieselbe Website und kann so mit der Session des Opfers unbemerkt alles sehen und tun, was das Opfer auch kann. Der Benutzer kriegt davon nichts mit!

Als Angreifer hab ich über XSS-ing also die Möglichkeit, Code im Browser eines Opfers auszuführen. 

Der Name XSS kommt daher zustande, da aus Sicht eines Opfers sein Browser nicht nur mit dem Webserver kommuniziert, den er besucht, sondern der Schadcode dann noch andere Webserver aufruft – üblicherweise mit bösartiger Absicht, um dorthin Daten zu schicken, oder auch um noch mehr Schadcode nachzuladen, wie Keylogger oder andere Trojaner. 

Durch XSS wurde der Browser in der Vergangenheit zur einer der größten Gefahren auf dem eigenen Rechner, da durch XSS viele potentielle Angriffe reinkommen. Die Browserhersteller haben aber in letzter Zeit viel dafür getan, dass dies zunehmen schwerer wird. Wie z.B. durch Einführung der Single Origin Policy. Dadurch ist XSS nun nur noch auf dem 7. Platz der OWASP Top-10, 2013 war es noch Platz 3.

Ist die Anwendung verwundbar?

Ursachen

Ursache für die Probleme bei XSS ist prinzipiell, dass ein Angreifer es schaffen kann, JS-Code einer fremden Webanwendung unterzujubeln. Die Webanwendungen wollen das natürlich nicht, statt dessen wollen sie es ermöglichen, dass Texte oder Daten eingegeben werden können. Wir haben auch hier wieder das Problem, dass anstatt Daten Befehle verarbeitet werden, genauso wie beim Thema Injection. Man will also Daten zulassen, aber keine Befehle. Die Benutzer sollen z.B. Texte wie Kommentare eingeben könne, oder auf Bilder und Videos, aber bitte keine Tags oder JS-Code, der die Webanwendung manipulieren könnte.

Prävention

Wie kann man also XSS verhindern?

Man muss immer davon ausgehen, dass Benutzereingaben generell gefährlich und potentiell böse sind. Und um die zu neutralisieren, muss man sämtliche Eingaben mit der entsprechenden Vorsicht behandeln. Man darf sie niemals ungefiltert verwenden und weiterverarbeiten.

Es gibt hier 2 Maßnahmen, die alle beide angewendet werden sollten:

  • Filterung aller Eingaben
  • Escaping aller Ausgaben

Nochmal ausführlicher:

Filterung der Eingaben

Alle Eingaben, die der Benutzer eingibt, müssen vor der Verarbeitung in der Anwendung gefiltert werden auf potenziell gefährliche Zeichen hin. Zeichen wie spitze Klammern z.B. sind immer Gefährlich im HTML-Umfeld, da sie Tags einleiten. Aber es gibt auch andere. Die Angriffsvektoren bei XSS sind vielfältig. 

Bei PHP bietet von Haus aus ein paar Funktionen an, die dabei helfen: (strip_tagshtmlentities und htmlspecialchars)

Außerdem gibt es Bibliotheken wie HTML-Purifier und htmLawed die man verwenden kann.

Bei Java Servlets ist es am effektivsten, einen Servlet-Filter zu schreiben, der bereits alle Http-Request-Parameter und Http-Header automatisch filtert. 

Für die Filterung der Eingaben bringen viele Entwicklungsframeworks bereits entsprechende Methoden mit, die man ebenfalls verwenden kann. Bei älteren Anwendungen kann man Libraries verwenden, die solche Filtermethoden anbieten. Z.B. ESAPI von OWASP.

Aber Vorsicht: Filterung der Eingabedaten ist nicht ausreichend, da es unmöglich ist, dabei alle Fälle zu berücksichtigen. Es werden immer neue Workarounds gefunden, wie man dann doch Schadcode einschleusen kann, ohne dass Filter es verhindern können. Deshalb brauchen wir unbedingt noch die 2. Maßnahme: 

Escaping der Ausgaben

Daten, die in der Webanwendung angezeigt werden sollen, werden dabei untersucht und kritische Zeichen werden HTML-encoded. Spitze Klammern werden dann durch entsprechende HTML-Entitäten ersetzt, so dass der Browser diese nicht als Tags interpretiert.

Das bedeutet also, das sämtliche Daten, die in der Webanwendung angezeigt werden entsprechend escaped werden sollen. Das betrifft übrigens nicht nur Daten, die direkt von Benutzer eingegeben wurden, sondern auch Daten die aus der DB kommen. Kreative Hacker versuchen auch über weiter Umwege XSS-Angriffsvektoren einzuschleusen, die dann letztendlich im Browser für Schadcode sorgen.

So wie beim Filtering gibt es auch fürs Escaping Methoden in Libraries, die hier hilfreich sind.

Fazit

Cross-Site-Scripting ist nach wie vor ein Thema das man beim Entwickeln von Webanwendungen definitiv auf dem Schirm haben sollte. Dieses Risiko kann mit relativ wenig Aufwand abgesichert werden, aber man muss sich drum kümmern.

Ob ich eine XSS-Schwachstelle in der Webanwendung habe, kann toolgestützt durch statische Codeanalyse herausgefunden werden. Sehr effektiv ist hier Datenflussanalyse, z.B. mit dem Tool Xanitizer – zu dem Tool werde ich übrigens auch bald ein separates Video machen.

Ich hoffe dieser Artikel ist hilfreich für Euch als Softwareentwickler – Anregungen und Feedback sind wie immer willkommen. Mehr über dieses Thema gibts in meiner Secure Coding Schulung – hier der Link zur Anmeldung: https://www.exxeta.com/de/exxeta-training/secure-coding

A7:2017 XSS: Cross-Site-Scripting
Cross-Site-Scripting Praxis