Internet-Gefahr

So funktionieren Cross-Site Scripting & CSRF

05.05.2010 von Hans-Christian Dirscherl
Cross-Site Scripting (XSS), CSRF und MySQL-Injection gehören zu den schlimmsten Bedrohungen im Internet. Wir erklären die technischen Grundlagen und sagen, wie Sie Ihre Kunden vor diesen Gefahren schützen können.

Cross-Site Scripting (XSS), CSRF und MySQL-Injection gehören zu den schlimmsten Bedrohungen im Internet. Wir erklären hier die technischen Grundlagen und sagen Ihnen, wie Sie Ihre Kunden vor diesen Gefahren schützen können.

XSS heißt eine Sicherheitslücke, durch die nahezu jedem Internetnutzer Gefahr droht. Vor allem in Foren und Weblogs, aber auch in online-basierten Anwendungen wie zum Beispiel Google Texte und Tabellen werden nahezu ununterbrochen XSS-Lücken entdeckt.

Cross-Site Scripting (die Abkürzung dafür lautet XSS und nicht wie eigentlich nahe liegenderweise CSS, weil CSS bereits als Kürzel für Cascading Stylesheets vergeben ist) besteht einfach gesagt darin, dass ein Angreifer Skript-Code in variable Bereiche auf einer Website oder in einer Internetanwendung an einer Stelle einfügt (und zur Ausführung bringt), wo dies eigentlich nicht möglich sein sollte beziehungsweise wo die Eingaben durch den Browser nicht ausreichend überprüft werden und in einem für den Anwender vertrauenswürdigen Context erscheinen.

XSS-Angriffe können mittels jeder von einem Browser interpretierbaren Skriptsprache erfolgen. Meist dürfte Javascript verwendet werden, aber auch VB-Skript/ASP.net oder ActiveScript (die Skriptsprache von Flash) sind möglich. In Javascript könnte ein ganz simples Script so aussehen:

<script>alert('XSS-Lücke eiskalt ausgenutzt')</script>

(Theoretisch sollte immer mit type="text/javascript“ beziehungsweise language=“javascript“ die genaue Skriptsprache angegeben werden. Unterbleibt jedoch die explizite Angabe der Skriptsprache, so gehen Browser standardmäßig davon aus, dass es sich um Javascript handelt).

Tippt man diesen Text in ein ungeschütztes Eingabefeld ein (das also Skripteingaben nicht mit geeigneten Programmiertechniken entschärft), dann sollte nach dem Abschicken des Formulars ein Pop-Up mit dem Text 'XSS-Lücker eiskalt ausgenutzt' aufgehen.

Wie Reseller ihren Kunden helfen können, die gesetzlichen Datenschutz-Bestimmungen einzuhalten, das erfahren Sie auf dem Channel-Sales-Day "Security" am 18. Mai in München. Hier können Sie sich für die kostenlose Veranstaltung anmelden.

Ein Beispiel zum Selbst-Ausprobieren von XSS

Sie wollen selbst ausprobieren, wie XSS funktioniert? Kein Problem, Sie benötigen dafür nur einen funktionierenden Webserver und eine einsatzbereite serverseitige Skriptsprache auf Ihrem PC (unter "Webserver" dürfen Sie sich also keine Maschine in einem Rechenzentrum oder bei einem Webhoster vorstellen, sondern ein Programm auf Ihrem PC, mit dem Sie eine Website bereit stellen können. Ein populäres Beispiel für einen Webserver ist der weit verbreitete und zudem kostenlos erhältliche Apache). Am einfachsten kommen Sie zu einem Webserver zu Testzwecken, wenn Sie ein Webserver-Paket wie XAMPP installieren (aktuell für Windows ist XAMPP 1.7.3, unter anderem mit dem Webserver Apache 2.2.14, der Datenbank MySQL 5.1.41, der Skriptsprache PHP 5.3.1, dem browserbasierten MySQL-Verwaltungsfrontend phpMyAdmin 3.2.4 und dem FTP-Server FileZilla 0.9.33).

Wenn Sie mit Windows arbeiten, können Sie sich hier das kostenlose Komplett-Paket von Xampp herunterladen. Installieren Sie Xampp wie auf der Projektseite beschrieben und starten Sie den Dienst Apache (Webserver); PHP (die Skriptsprache, mit der Sie dynamische Elemente und Datenbankverbindungen in die Website integrieren können) steht nach der Installation des Xampp-Paketes ohnehin zur Verfügung.

Sollten Sie mit Linux arbeiten, so ist ja nach Distribution Apache bereits installiert und läuft vielleicht auch schon. Überprüfen Sie das, indem Sie in der Dienste-/Dämonenverwaltung Ihrer Distribution nach Apache, Apache2 oder httpd suchen. Gegebenenfalls ist Apache bereits installiert, muss aber noch gestartet werden. Der dafür erforderliche Befehl ist je nach Distribution unterschiedlich, unter Ubuntu müssen Sie beispielsweise auf der Kommandozeile

sudo /etc/init.d/apache2 start

eintippen.

Ob der Apache läuft bekommen Sie mit einem ganz einfachen Test heraus: Geben Sie in die Adresszeile des Browsers "http://localhost/" ein. Apache sollte mit einer Meldung wie "It works!" antworten. Ob PHP auf Ihrem Rechner funktioniert, bekommen Sie ebenfalls relativ einfach raus: Öffnen Sie einen Texteditor und geben Sie folgenden Text ein:

<?php phpinfo(); ?>

Speichern Sie die Datei als phpinfo.php im Dokumentverzeichnis Ihres Webservers (beim Xampp-Paket heißt es htdocs) und geben Sie dann in die URL-Zeile localhost/phpinfo.php ein. Jetzt sollte eine Website mit Details zur Konfiguration von PHP erscheinen, diese Details brauchen Sie aber nicht weiter zu interessieren, mit einer Ausnahme:

Bei den Einträgen zu "magic_quotes" muss „off“ stehen! Sollte das nicht der Fall sein, so müssen Sie die für Ihren Server zuständige php.ini suchen (deren Speicherort geht aus der phpinfo() hervor) und den Eintrag für magic-quotes von on auf off ändern. Diese Konfigurations-Datei, die das Verhalten von PHP steuert, existiert auf Ihrem PC mehrmals. Bei einer Xampp-Installation finden Sie eine php.ini beispielsweise im Apache/bin-Verzeichnis und im PHP-Verzeichnis. Öffne Sie die Dateien mit einem simplen Texteditor oder einem HTML-Editor, suchen Sie den Eintrag magic_quotes_gpc (das gpc steht übrigens für GET, POST, Cookie) und ersetzen Sie on durch off. Verfahren Sie bei den beiden anderen magic_quotes-Einträgen genauso. Speichern Sie danach die php.ini-Dateien und starten Sie den Webserver mit Hilfe des Xampp-Control-Panels beziehungsweise der passenden Betriebssystembefehle neu, unter Ubuntu Linux beispielsweise:

sudo /etc/init.d/apache2 restart

Erstellen Sie nun mit PHP ein einfaches Eingabe-Formular. Tippen Sie folgenden Quelltext in einen Editor Ihrer Wahl (Vorsicht: der Editor darf keine zusätzlichen Zeichen außer Ihrem Quellcode abspeichern) und speichern Sie die Datei unter einem beliebigen Namen und mit der Endung .php im Dokument-Verzeichnis Ihres Webservers:

<?php
$eingabe = $_POST['eingabe'];
if ($eingabe) echo $eingabe;
else echo "<html><body><form action='xsstest.php' method='POST'><input type='text' name='eingabe'><input type='submit' value='Absenden'></body></html>"; ?>

Starten Sie nun die Datei wieder durch Eingabe in die URL-Zeile Ihres Browsers: localhost/dateiname.php. Jetzt sollten Sie, sofern Ihnen keine Syntaxfehler bei der Eingabe des Quellcodes unterlaufen sind, das Formular sehen. Tippen Sie in das Eingabefeld folgenden Text ein:

<script>alert('XSS-Lücke eiskalt ausgenutzt')</script>

und drücken Sie danach den "Absenden"-Button. Nun sollte bei Ihnen ein Popup aufgehen. Wichtig: Javascript darf im Browser nicht abschaltet sein und es darf kein Popup-Blocker laufen.

Zur Erklärung: Bei diesem Beispiel haben Sie eine Zeile Javascript in ein HTML-Formular eingefügt. Das Formular wird durch ein kleines in der Skriptsprache PHP programmiertes Skript ausgewertet (was auf vielen Websites gängige Praxis ist) und das Ergebnis dann im Browser ausgegeben. Der Browser kann nicht zwischen erwünschten und unerwünschten Inhalten und auch nicht zwischen Programmiercode, der vom Ersteller der Website stammt und zwischen Code, der von einem Angreifer untergeschoben wurde, unterscheiden und liefert das Ergebnis mit dem kleinen Javascript aus.

XSS kann überall lauern

XSS kann in Foren, Weblogs, Online-Shops und überall, wo Eingaben auf dynamischen Websites möglich sind, erfolgen. Typische Einfallstore sind also Suchformulare, Login-Felder, Eingabefelder in Foren oder eben die Warenkörbe von Online-Shops, aber auch Mailclients, wenn die digitale Post als HTML-Mails oder Mails mit eingefügten Links vorliegen (übrigens müssen Links keineswegs immer angeklickt werden. Wenn ein Eventhandler wie onmouseover benutzt wird, reicht es schon aus, wenn der Anwender den Mauszeiger über einen Link bewegt).

Da dynamische Websites mittlerweile fast schon der Standard sind, können nahezu überall XSS-Attacken lauern. Die weite Verbreitung von AJAX als Schlüsseltechnologie des so genannten Web 2.0 dürfte zudem immer wieder neue Sicherheitslücken aufreißen, die sich dann teilweise auch für XSS-Angriffe ausnutzen lassen.

XSS-Lücken treten übrigens keineswegs nur in selbst gestrickten Websites auf, sondern werden in den gängigen Sicherheits-Mailinglisten nahezu ständig für bekannte und beliebte Anwendungen wie zum Beispiel phpMyAdmin oder Google Texte und Tabellen gemeldet. Eine XSS-Lücke wurde vor einiger Zeit auch im Online-Bezahlservice Papypal entdeckt.

Welcher Schaden kann durch XSS konkret entstehen?

Sicherheitsexperten unterscheiden insgesamt drei Arten von XSS, von denen besonders zwei weit verbreitet sind: Reflektiertes XSS, bei dem der eingeschleuste Schadcode umgehend an den User versandt wird. Beispielsweise, indem der Angreifer eine URL verschickt, deren Ziel-Website Code mit Ausnutzung einer XSS-Lücke enthält. Und persistentes XSS, bei dem der Schadcode zunächst in der Datenbank der angegriffenen Website gespeichert wird. Erst wenn ein Anwender dieser Inhalt von einem User aufgerufen wird, wird der Schadcode ausgeführt. Noch eher selten ist dagegen DOM-XSS, bei dem in statischen HTML-Seiten dank Javascript Schadcode eingefügt wird, indem eine verseuchte URL geladen wird. Das klappt aber nur bei Browsern, die Sonderzeichen in der URL nicht verarbeiten.

Das kann ein Angreifer erreichen, wenn er eine XSS-Lücke ausnutzt:

Website Defacement

Das Aussehen der Website kann durch XSS verändert respektive entstellt werden. Defacement nennt man diesen Vorgang, wenn ein Hacker eine XSS-Lücke ausnutzt und zum Beispiel seine eigenen CSS-Daten in die fremde Website einbaut (CSS - Cascading Style Sheets - sind das Hauptwerkzeug, mit dem das Aussehen einer Website bestimmt wird). So kann der Angreifer die Farbgebung auf der Seite verändern oder Seitenelemente ausblenden beziehungsweise deren Gestaltung ändern. Im weitesten Sinne kann man es auch zum Website Defacement zählen, wenn der Angreifer sich einen Spaß erlaubt und störende Popups einblendet.

Oder aber der Hacker lädt seine eigenen Bilder auf die attackierte Seite hoch. Website Defacement mag zunächst als eher lästig und fast wie ein eher harmloser Scherz erscheinen, weil dadurch keine sensiblen Daten verloren gehen und auch keine Malware auf den Rechner des Besuchers eingeschleust wird. Doch auch durch Defacement kann spürbarer Schaden entstehen: Wenn zum Beispiel die Kunden einen seriösen Online-Shops plötzlich leicht bekleidete Damen in anzüglichen Posen begrüßen, ist der Imageschaden und Vertrauensverlust für den Shop-Betreiber immens.

Datenverlust und -Diebstahl

Login-Daten wie Nutzernamen und Passwörter, aber auch Cookie-Inhalte können aufgrund von XSS ausgelesen werden und damit in falsche Hände geraten. Angreifer können Session-IDs abfangen, damit dessen Sitzung übernehmen und unter seinem Namen agieren – beispielsweise in einem Online-Shop. Selbst wenn nur Cookies und keine Session-IDs erobert werden, lässt sich damit beispielsweise das Einkaufsverhalten eines Anwenders rekonstruieren. Ebenso können die Inhalte von Webanwendungen ausgelesen werden.

Oder der Anwender wird gegen seinen Willen auf eine andere Seite weiter geleitet. Voraussetzung dafür, dass ein Anwender in eine XSS-Falle tappt, ist, dass der XSS-Code in einem vertrauenswürdigen Umfeld platziert wird.

Serverüberlastung/DDoS-Attacken

XSS kann auch dazu benutzt werden, um von gekaperten Rechnern aus immer wieder Anfragen an einen bestimmten Server abzuschicken. Passiert das von vielen PCs aus, kann der angegriffene Server in die Knie gehen und nicht mehr antworten.

Wie können sich Anwender und Webseiten-Besitzer schützen?

Aus Anwendersicht gibt es eine einfache, aber nicht unbedingt zweckmäßige Schutzmaßnahme: Wenn man Javascript und Skriptsprachen/Flash im Browser deaktiviert, ist klassisches XSS via Script natürlich nicht mehr möglich. Allerdings schränkt man damit erheblich das Surfvergnügen und die Nutzbarkeit vieler Webseiten ein, so dass das Abschalten von Javascript nicht generell empfohlen werden kann.

Tipp: Sie können Skripte unter Firefox bequem mit dem kostenlosen Addon Noscript steuern. Damit können Sie für jede besuchte Website exakt festlegen, welche Skripte gestartet und welche blockiert werden sollen.

In Mailclients kann man zudem die HTML-Funktion deaktivieren, wenn man mehr Sicherheit wünscht.

Was machen Administratoren und Webseitenbesitzer?

Aus dem oben Gesagten wird klar: Der Schutz gegen XSS ist in erster Linie die Aufgabe der Webseiten-Besitzer. Das A und O zum Schutz gegen XSS ist zudem schnell formuliert: Alle Eingaben müssen auf ihre Plausibilität geprüft werden: Stimmt die Länge der Eingaben, ist es der richtige Datentyp (wenn beispielsweise nur die Eingabe einer Zahl erwartet wird, sollte keine Zeichenkette in der Variable stehen) und – besonders wichtig - enthält die Eingabe Sonderzeichen beziehungsweise HTML- oder Scriptcode?

In der weit verbreiteten Skriptsprache PHP können HTML-Tags beispielsweise mit dem Befehl strip_tags() ausgefiltert werden. Dabei lassen sich gegebenenfalls einzelne Tags, die sinnvoll erscheinen, explizit zulassen. Wer in einem Forum umfangreichere Formatierungsmöglichkeiten für Eingaben zulassen möchte, kann als Alternative zu HTML eine spezielle Auszeichnungssprache wie BBCode einsetzen. Bei BBCode kann ein Forumsteilnehmer seine Texte ähnliche wie bei HTML formatieren, also zum Beispiel fett hervorheben, URLs hinterlegen oder die Schriftgröße variieren. Nur erfolgt das eben nicht mit echtem HTML (das durch <> markiert wird), sondern mit BBCode-Zeichen, die zwischen [] stehen. Die Eingaben werden nach dem Absenden von eventuell eingefügten HTML bereinigt, danach werden die ungefährlichen BBCode-Elemente in HTML umgesetzt.

Sonderzeichen wie ' und “ werden maskiert, indem ihnen ein Backslash vorangestellt wird: \. Dafür stellen Sprachen wie PHP fertige Konfigurationsmöglichkeiten bereit: magic_quotes_gpc. Man kann das aber auch händisch mit Befehlen wie addshlashes() machen. Filtert man Eingaben mit Befehlen wie htmlspecialchars() oder htmlentities(), so werden radikal alle HTML-Sonderzeichen in den entsprechenden Entity-Code umgewandelt und können keinen Schaden mehr anrichten: aus einem ' wird dann &#039; und aus “ wird &quot;. Bei dieser radikalen Lösung bekommt man zwar maximale Sicherheit, allerdings um den Preis, das keine Formatierungen mehr möglich sind.

Probieren Sie diesen Schutzmechanismus einfach mit unserem einfachen Formular aus. Ändern Sie die Zeile, in der $_eingabe = $_POST['eingabe']; steht in: $_eingabe = htmlentities($_POST['eingabe']);

<?php
$eingabe = htmlentities($_POST['eingabe']);
if ($eingabe) echo $eingabe;
else echo "<html><body><form action='xsstest.php' method='POST'><input type='text' name='eingabe'><input type='submit' value='Absenden'></body></html>";
?>

Speichern Sie das Skript erneut und rufen Sie die Website dann erneut im Browser auf. Geben Sie erneut das obige kurze Javascript ein. Jetzt sollte kein Popup mehr erscheinen.

Alternative Schutzmechanismen sind Whitelist- und Blacklist-Überprüfungen. Bei ersteren wird festgelegt, welche Eingaben in einem Formular generell erlaubt sind: HTML Purifier ist eine solche Hilfsanwendung. Eingaben, die nicht explizit erlaubt sind, sind nicht möglich. Blacklists funktionieren genau umgekehrt: Hier wird festgelegt, was generell untersagt ist. Das setzt aber voraus, dass sich der Programmierer über alle potenziellen Angriffsmöglichkeiten und Sicherheitslücken bewusst ist und seine Blacklists immer umgehend an neue Bedrohungsszenarien anpasst. Somit sind Blacklists aufwändiger zu warten als Whitelists und letztendlich anfälliger für bis dato unbekannte Schwachstellen.

Für Programmiersprachen wie PHP gibt es Projekte, die versuchen, die Sprache insgesamt sicherer zu machen. Suhosin ist so ein Projekt, das PHP-Anwendungen und den PHP-Kern schützt und beispielsweise Mechanismen bereit stellt, um Session- und Cookie-Daten vor Diebstahl via XSS-Angriffen zu schützen.

Die gefährlichen Schwestern: Cross-Site Request Forgery, Cross-Site Authentication und MySQL Injection

Bei Cross-Site Request Forgery (CSRF) - diese Gefahr ist aktuell in den Schlagzeilen - führt der Angreifer im Namen eines Opfers eine Aktion auf einer Website aus. Vereinfacht gesagt: XSS wird ausgenutzt, um Code im Browser des Benutzers auszuführen – bei CSRF werden die im Browser gespeicherten Informationen missbraucht, um im Namen des ahnungslosen Users Aktionen auf einer Website durchzuführen. Das ist der Fall, wenn ein Angreifer die Session-ID eines Anwenders kapert (weil der Anwender sich bei seinem letzten Besuch im Shop nicht korrekt ausgeloggt hat) und damit in einem Online-Shop einkauft, Session-Riding heißt dafür der Fachbegriff.

Beim verwandten Cross-Site Authentication werden einem Internetnutzer Zugangsdaten geklaut, indem man ihm ein gefälschtes Login-Formular vorgaukelt. Zum Beispiel, indem ein Angreifer ein Bild in einem als vertrauenswürdig angesehenen Forum platziert, für das man sich angeblich erst einloggen muss, wenn man es sehen will. Die dabei eingegebenen Logik-Daten schnappt sich dann der Angreifer.

(My)SQL Injektion heißt eine weitere ernste Bedrohung, die seit einiger Zeit von sich reden macht. Der augenscheinlich größte Unterschied aus der Sicht des Anwenders: Während XSS direkt gegen den Anwender und dessen Client gerichtet ist, zielt ein Angriff mittels MySQL Injektion auf den Website-Betreiber, genauer gesagt auf dessen MySQL-Datenbank. In der Konsequenz ist aber auch hier der Anwender das Opfer. Denn ob er nun direkt via XSS das Ziel eines Betrugsversuches wird oder aber beispielsweise seine Kundendaten wie Adresse oder Bankverbindung durch eine erfolgreiche MySQL Injection in falsche Hände geraten, der Leidtragende ist immer der Internetanwender.

Bei SQL-Injection schleust der Angreifer gegen den Willen des Datenbankbetreibers SQL-Befehle in die SQL-Datenbank ein. Er nutzt dazu genauso wie bei XSS-Hacks die unzureichende Validierung der Benutzereingaben aus. Mit den eingeschleusten SQL-Befehlen kann der Angreifer dann die Inhalte der Datenbank auslesen, beeinflussen (also beispielsweise Daten löschen oder deren Werte ändern) oder löschen. Auch hier besteht der Schutz im Maskieren von Sonderzeichen und verwandten Mechanismen. Bei Redaktionsschluss wurden etliche SQL Injections bei diversen Websites aus China und Taiwan gemeldet. (PCW/rw)