Skip to content

XSS-Schwachstellen finden, Teil 1: Einfachste Fälle

Ab dieser Folge geht es um die Frage, wie Sie XSS-Schwachstellen in Ihrer Webanwendung finden können. Das ist gar nicht so schwer, wie Sie vielleicht vermuten. Oder schwerer, als Sie auf den ersten Blick dachten. Je nachdem, für wie schwierig oder leicht Sie die Suche halten.

Voraussetzungen für XSS

Die erste Voraussetzung für eine Cross-Site-Scripting-Schwachstelle ist eine fehlende oder mangelhafte Prüfung von Benutzereingaben: Immer, wenn über einen Parameter (auch) HTML- oder JavaScript-Code eingegeben werden kann, besteht Gefahr.

Auch dann, wenn eigentlich niemand den Parameter für solche Eingaben verwenden würde wie zum Beispiel in Parametern für Namen, Adressen, Benutzernamen, Geburtsdaten und ähnlichem. Denn es stimmt nicht, das "niemand" dort HTML- und/oder JavaScript-Code eingeben würde - ein Cyberkrimineller würde es tun, wenn er darüber eine XSS-Schwachstelle ausnutzen kann. Es müssen also zumindest unerwünschte Tags ausgefiltert werden, bevor die eingegebenen Daten ausgegeben oder von der Webanwendung gespeichert werden.

Und damit sind wir schon bei der zweiten Voraussetzung: Die präparierten Benutzereingaben müssen an einen Benutzer ausgegeben werden. Dabei ist es egal, ob das regulär zum Beispiel bei der Anzeige eines Suchbegriffs der Suchfunktion oder bei der Ausgabe eines Gästebuch-Eintrags oder Kommentars passiert, oder ob der Wert eines Parameters im Rahmen einer Fehlermeldung angezeigt wird.

Ob das der gleiche Benutzer oder ein anderer ist, ist ebenfalls erst mal unerheblich. Diese Unterscheidung wird erst interessant, wenn es um die Durchführbarkeit eines Angriffs geht. Dann gibt es einige mögliche Kombinationen:

  • Die Daten werden über die URL übertragen und in der aufgebauten Webseite an den Benutzer zurückgegeben. Formal bedeutet das, jeder Benutzer bekommt die von ihm selbst eingegebenen Daten zurückgeliefert. Das lässt sich für einen XSS-Angriff ausnutzen, es handelt sich um das klassische reflektierte Cross-Site-Scripting: Der Angreifer schiebt dem Opfer einen präparierte Link unter, und wenn das Opfer den Link aufruft, wird der eingeschleuste Code von der Webanwendung in die ausgelieferte Seite integriert und im Webbrowser des Opfers ausgeführt.
  • Die Daten werden auf dem Webserver gespeichert. Wird danach ein so präparierter Eintrag aufgerufen, wird der eingeschleuste Code im Webbrowser des Aufrufers ausgeführt. Hierbei handelt es sich um persistentes Cross-Site-Scripting (auch JavaScript-Injection genannt).
  • Kann der präparierte Eintrag nur vom ursprünglichen Benutzer, also dem Angreifer, aufgerufen werden, ist streng genommen kein XSS-Angriff möglich (oder nur ein sehr nutzloser Angriff gegen sich selbst). Trotzdem sollten die Daten auch in diesem Fall geprüft werden. Zum einen aus Prinzip, ungeprüfte Benutzereingaben stellen immer eine potentielle Gefahr dar. Zum anderen, weil evtl. doch andere Benutzer an diese Daten gelangen könnten. Das könnte zum Beispiel passieren, wenn ein Administrator einen Eintrag nach einer Beschwerde prüft. Niemand hindert den Angreifer daran, Schadcode in eine nur für ihn zugängliche Seite einzuschleusen und dann einen Administrator wegen einer angeblichen Fehlfunktion zum Betrachten der Seite zu bewegen.

Traue nie dem Client - Alle Eingaben sind gefährlich!

Potentiell sind alle Benutzereingaben für Cross-Site-Scripting brauchbar. Außer den klassischen Fällen wie Suchwörtern, Kommentaren und Forenbeiträgen kann der XSS-Code auch über zum Beispiel Benutzernamen, SQL- oder 404-Fehlermeldungen erzeugende Daten oder manipulierte HTTP-Header eingeschleust werden. Alles Daten, die vom Client geliefert und daher vom Angreifer manipuliert werden können, müssen auf eingeschleusten XSS-Code geprüft werden, bevor sie direkt an den Benutzer zurückgegeben oder für eine spätere Verwendung von der Webanwendung gespeichert werden. Dabei ist mit Benutzer nicht nur der eigentliche Benutzer der Webanwendung gemeint. Auch Administratoren, die für normale Benutzer nicht zugängliche Daten wie zum Beispiel Logfiles in einem Webbrowser betrachten, können das Opfer von XSS-Angriffen werden.

Sehr einfache XSS-Schwachstellen finden

Finden keinerlei Prüfungen statt, können potentiell gefährliche Parameter durch das simple Eingeben eines Testcodes wie zum Beispiel des altbekannten

<script>alert('XSS')</script>

überprüft werden. Werden mehrere Parameter auf einmal getestet, kann zur Unterscheidung der Parameter deren jeweiliger Name in die Meldung übernommen werden:

http://www.beispiel.example/index.php?name=<script>alert('XSS über name')</script>
&password=<script>alert('XSS über password')</script>

Außer Formularfeldern (einschließlich versteckten) und URL-Parametern müssen auch Cookies und, sofern von der Webanwendung verwendet, HTTP-Header geprüft werden.

Das einfachste Verfahren funktioniert oft nicht (mehr)

Mit dem obigen Test-Code finden Sie aber nur die allersimpelsten XSS-Schwachstellen. Meist kommen Sie so nicht zum Ziel. Entweder, weil der eingeschleuste Code an einer Stelle ausgegeben wird, an der er nicht ausgeführt wird. Oder weil ein XSS-Filter Teile des Codes wie zum Beispiel die < und > oder auch ganze Tags ausfiltert und ihn damit unbrauchbar macht.

Wenn sich die Schwachstellen nicht freiwillig melden, bleibt nur die mühsame Suche nach ihnen. Um die kommen Sie aber generell nicht herum. Denn auch wenn zum Beispiel bei der Eingabe des obigen Testcodes in das Eingabefeld für die Suchfunktion der Webanwendung die Alertbox aufgeht, nicht aber bei der Eingabe in zum Beispiel einen Gästebuch-Eintrag, bedeutet das noch lange nicht, dass über das Gästebuch kein XSS möglich ist.

Schritt 1: Welche Parameter werden an den Benutzer ausgegeben?

Am Anfang der Suche nach XSS-Schwachstellen steht die Suche nach Parametern, die für den Angriff in Frage gekommen. Für jeden vorhandenen Parameter muss festgestellt werden, ob und wenn ja wo er ausgegeben wird. Dazu können Sie ein einfaches Testmuster wie zum Beispiel die Zeichenkette IIIXSSTestParameternameIII verwenden.

Es ist hilfreich, wenn das Testmuster im Quelltext der ausgegebenen HTML-Seiten leicht auffällt, so dass man sofort sieht, in welchem Kontext der Parameter ausgegeben wird. Außerdem sollte die Seite den Teststring nicht regulär enthalten, sonst hätte man nur False Postives zu untersuchen. Wieso der Parametername im Testmuster enthalten ist werden Sie gleich sehen, sofern Sie es sich nicht bereits denken können.

Geben Sie das Testmuster der Reihe nach für jeden vorhandenen Parameter ein und prüfen Sie, wo und in welchem Kontext es auf der danach ausgegebenen Webseite auftaucht. Der Kontext ist wichtig, da der Angriff oft daran angepasst werden muss, aber dazu später mehr.

Mit diesem Ansatz erfassen Sie alle Fälle, die für reflektiertes XSS in Frage kommen. Bei der Suche nach Parametern, die möglicherweise persistentes XSS erlauben, wird es etwas kniffliger: Sie müssen in jeder ausgegebenen Seite auch prüfen, ob weitere Parameter ausgegeben wurden, die bereits in einem früheren Schritt getestet wurden - deshalb auch der Parametername als Bestandteil des Testmusters. Denn nur so können Sie erkennen, wo zum Beispiel Benutzernamen, Gästebuch- und Foreneinträge und ähnliches ausgegeben werden.

Nachdem Sie eine Liste aller zu testenden Parameter und ihrer Ausgabeorte haben, kann der eigentliche Test beginnen. Wie, erfahren Sie in der nächsten Folge.

Carsten Eilers

Trackbacks

Dipl.-Inform. Carsten Eilers am : XSS-Suche, Teil 3: Der Kontext bestimmt den Test

Vorschau anzeigen
Nachdem Sie alle möglicherweise für XSS anfälligen Parameter der Webanwendung ermittelt und eine möglicherweise vorhandene Schutzfunktion erkannt haben, kann die Suche nach XSS-Schwachstellen los gehen. Je nachdem, wo e