JavaScript/Tutorials/Cross Site Scripting

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Cross-Site Scripting (XSS, engl. für Webseitenübergreifendes Skripting) ist das Einschleusen von fremden, möglicherweise schädlichen JavaScripten in eine Website. Es handelt sich weniger um ein Sicherheitsproblem innerhalb von JavaScript, sondern um eine Sicherheitslücke in fehlerhaften Webanwendungen, die Daten aus nicht vertrauenswürdigen Quellen (z. B. aus Formulareingaben oder HTTP-Parametern) ungefiltert ins HTML einbauen.

Funktionsweise

XSS ist eine Art HTML Injection. Es tritt dann auf, wenn eine Webanwendung Benutzereingaben annimmt und diese Daten dann an einen Browser weitersendet, ohne den Inhalt zu überprüfen. Damit ist es einem Angreifer möglich, auch Skripte indirekt an den Browser des Opfers zu senden und damit bösartigen Code (malicious code) auf der Seite des Clients auszuführen.

Häufige Anwendungsbereiche sind dynamisch erzeugte Webseiten wie Gästebücher, Foren und Kommentarfunktionen, aber auch die Kontrollausgabe von eingegebenen Bestellungen, Registrierungen oder Suchanfragen. Die eingegebenen Daten werden auf der Webseite wieder als Seiteninhalt ausgegeben, wenn die Seite von Benutzern aufgerufen wird. So ist es möglich, manipulierte Daten und bösartigen Code an alle Benutzer zu senden, sofern das Serverskript dies nicht verhindert.

Code kann bösartig sein, denn JavaScript kann …

Mit diesen Fähigkeiten können mehrere Angriffe ausgeführt werden:

  • Cookie-Diebstahl: der Angreifer kann mit document.cookie auf Cookies zugreifen, zu seinem Server senden und dort Daten wie Session-IDs auslesen.
  • Keylogging: über einen keyboard-EventListener können alle Tastaturanschläge mitverfolgt und an den eigenen Server gesendet werden, sodass sensible Daten wie Passwörter und Kreditkartennummern gestohlen werden.
  • Phishing: über gefälschte Login-Formulare werden Benutzername und Passwort abgefragt und dann übernommen.

XSS-Lücken in großen Webanwendungen wie MySpace, Facebook und Twitter haben spektakuläre JavaScript-Würmer möglich gemacht. Diese pflanzten sich innerhalb der Website z. B. über Benutzerprofile fort, konnten private Daten auslesen oder löschen (Phishing) und damit großen Schaden anrichten. Es gibt auch XSS-Würmer, die andere Domains mit derselben Webanwendung (z. B. der Blogsoftware WordPress) infizierten und sich so über Webserver hinweg verbreiteten.

Angriffsarten

Es gibt drei Typen von Angriffsarten, mit denen Schadcode eingeschleust werden kann. Aus Gründen der Vereinfachung wird für potentiell bösartigen Code nur

<script>…</script>

verwendet.

Reflektiert oder nicht-persistent

Das nicht-persistente (non-persistent) oder reflektierte (reflected) Cross-Site-Scripting ist ein Angriff, bei dem eine Benutzereingabe vom Server wieder direkt zurückgesendet und in einer Kontrollausgabe verarbeitet wird. Enthält diese Eingabe Skriptcode, der vom Browser des Benutzers anschließend interpretiert wird, kann dort Schadcode ausgeführt werden.

Der Angriff ist nicht-persistent, da der Schadcode nur temporär bei der jeweiligen Generierung der Webseite eingeschleust, nicht aber gespeichert wird. Ruft man die Seite danach ohne die manipulierte URL oder das manipulierte Formular auf, ist der Schadcode nicht mehr enthalten.

Beispielsweise wird bei einer Suche oft der Suchbegriff auf der Ergebnisseite wieder ausgegeben(„reflektiert“): Der Funktion kann der Suchbegriff entweder per URL-Argument oder über ein Formular übertragen werden. Eine solche Anfrage sieht damit etwa so aus: https://example.com/?suche=Suchbegriff

Die übergebenen Suchbegriffe werden nun von einer serverseitigen Webapplikation ungeprüft auf der Ergebnisseite wieder ausgegeben:

 <p>Sie suchten nach: Suchbegriff</p>

Würde nun hier folgender Suchbegriff verwendet: <script>…</script>, würde dann folgender HTML-Code erzeugt:

<p>Sie suchten nach: <script>…</script></p>

Nach dem gleichen Prinzip kann auch über manipulierte Formulare oder Formulareingaben Schadcode eingeschleust werden. Hierbei muss das Opfer auf eine Webseite mit einem manipulierten Formular gelockt werden. Das Formular kann dabei in einem iframe unsichtbar im Hintergrund geladen und per JavaScript automatisch abgeschickt werden, sodass eine Interaktion des Benutzers nicht erforderlich ist.

Persistent

Bei persistentem (persistent) oder beständigem (stored) Cross-Site-Scripting wird eingegebener Schadcode auf dem Webserver gespeichert und später wieder an weitere Benutzer ausgeliefert. Dies können Blogs, Foren und Gästebücher sein, bei denen Besucher Kommentare, Nachrichten oder Grüße hinterlassen können. Die eingetragenen Daten werden serverseitig in einer Datenbank gespeichert und bei jedem Aufruf wieder ausgegeben.

Wird nun hier als Nachricht Folgendes eingegeben:

Toller Artikel!<script>…</script>

würde diese bei jedem Aufruf ausgeliefert und das Skript vom Browser des Benutzers ausgeführt.

Beispiel
<p id="kommentar">Toller Artikel!<script></script></p>

DOM-basiert oder lokal

DOM-basiertes XSS ist eine Variante von sowohl persistentem als auch reflektiertem XSS. In einem DOM-basierten XSS-Angriff, wird der Schadcode erst geparst, wenn legitimes JavaScript ausgeführt wird.

  1. Der Angreifer erzeugt eine URL, die Schadcode enthält und sendet diese ans Opfer.
  2. Das Opfer wird von Angreifer so getäuscht, dass dieser die URL in einem Request anfordert.
  3. Die Webseite erhält den Request aber nicht dem Schadcode.
  4. Der Browser des Opfers führt das legitime JavaScript innerhalb der Response aus, sodass der Schadcode in die Seite eingefügt wird.
  5. Der Browser des Opfers führt den Schadcode aus und sendet alle cookies des Opfers zum Server des Angreifers.

Schutz

Um XSS zu verhindern, muss verhindert werden, dass eingegebene Daten Skripte enthalten können.

Maskierung von Code

Alle Benutzereingaben sollten so maskiert werden, dass der Browser diese nicht als Code verarbeiten, sondern nur als Daten darstellen kann. Die einfachste Form der Maskierung ist die Ersetzung der einleitenden spitzen Klammer bei HTML-Tags durch ein &lt;.

Maskierung von HTML-Code
Eingabe <script></script>

Eingabe &lt;script>…</script>
Durch die maskierte einleitende spitze Klammer wird das script-Tag vom Browser nicht geparst.


Hierbei gilt es aber zu berücksichtigen, dass Daten in verschiedenen Kontexten erhoben werden und dadurch unterschiedlich behandelt werden müssen.

Kontext BeispielCode
HTML – Elementinhalt <div>Eingabe</div>
HTML – Attributwert <input value="Eingabe">
URL-Parameter http://example.com/?parameter=Eingabe
CSS Wert color: Eingabe
JavaScript Wert var name = "Eingabe";
Hauptartikel: Programmiertechnik/Kontextwechsel/erkennen und behandeln


Auch Attributwerte von HTML-Elementen können für eine HTML-Injektion missbraucht werden. Das Eingabefeld

<input value="eingabe">

wird durch die Eingabe von "><script>...</script><input value=" zu

<input value=""><script>…</script><input value="">


Auch URL-Parameter bieten eine Eintrittsquelle.

Injektion von Javascript in eine URL
document.querySelector('a').href = Eingabe ;
Obwohl die Zuweisung einer Variablen zum href-Attribut schon für eine Maskierung sorgt, ist trotzdem die Eingabe von javascript:… möglich, die durch einen Klick auf den Link ausgeführt wird.

Validierung

Um XSS-Lücken zu vermeiden, ist eine sorgfältige Prüfung, Filterung und Entschärfung aller nicht vertrauenswürdiger Daten nötig, die in den HTML-, CSS- und JavaScript-Code server- oder clientseitig eingebaut werden.

Dabei kann eine browsereigene Validierung wichtige Vorarbeit leisten; wirklich sicher werden Benutzereingaben aber nur durch eine serverseitige Überprüfung und Validierung aller Benutzereingaben.

So könnten Sie Script-Elemente und andere in einer Sperrliste (black list) vorhandene Ausdrücke aus den Eingaben herausfiltern. Da aber immer wieder neue, vorher unbekannte Lücken auftreten, ist es besser erwünschten Code in einer Positivliste (white list) zu notieren und alles andere herauszufiltern.

Um empfangenes HTML zu filtern, können Sie auch fertige PHP-Skripte wie den http://htmlpurifier.org/ verwenden.

Siehe auch


Weblinks