contao/test — Issue #2751: Sicherheitsluecke: Header-Injection und Cross-Site-Scripting
Author: importer
Created: 2011-11-29 10:14:40+00:00
State: open
Labels: comments, Defect

Während eines internen Sourcecode Audits konnte ich feststellen, dass es möglich ist mittels einer gezielten Header Injection eigenen Javascript-Code in das Backend (Datenbank) des Contao CMS zu platzieren.

Schwachstellenbeschreibung:

Der Angreifer benutzt die Webanwendung als Vehikel, indem er bösartige Javascript- oder weitere HTML-Objekte, wie Flash, einbindet. Dadurch kann der Angreifer alle Daten, auf die der Browser Zugriff hat, lesen, ändern und verschicken. Das bedeutet, dass der Angreifer auch Inhalte von Webseiten verändern kann. Durch die Kontrolle über den Browser lassen sich alle benutzerspezifischen Eingaben, etwa bei einem Anmeldeformular, während der Laufzeit auslesen. Ferner kann der Angreifer falsche Informationen anzeigen oder den Besucher arglistig täuschen, indem er Formulare auf andere Systeme umleitet, um so Passwörter auszuspionieren. Mittlerweile ist die Auskundschaftung eines vorhandenen internen Netzwerks, Port Scan von internen Systemen usw. mit Cross-Site Scripting (XSS) möglich. Die Verbreitung von Würmern, Trojanern und weiterer Schadsoftware mittels XSS ist ebenfalls durchführbar.

Hier die Details:

**1.1 /system/libraries/Environment.php, Zeile 316-324, Funktion ip():**

Die Funktion ip() soll die IP des Benutzers wiedergeben und - falls ein Proxy den Header X_FORWARDED_FOR mitsendet, diese verwenden.

```
protected function ip()
{
return !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
}
```

Wie hier zu sehen ist, wird vorzugsweise der X_FORWARDED_FOR Header ungefiltert zurückgegeben. Wird später ein Kommentar gespeichert, so wird für diesen jeweils die IP gespeichert:

**/system/modules/comments/Comments.php, Zeile 257,271**

```
// Prepare the record
$arrSet = array
(
[...]
'ip' => $this->Environment->ip,
[...]
);

$insertId = $this->Database->prepare("INSERT INTO tl_comments %s")->set($arrSet)->execute()->insertId;
```

Wie hier zu sehen ist, wird keine weitere Filterung für den Rückgabewert der Environment-ip funktion getätigt. Wir können also jeglichen Inhalt in die Datenbank einfügen. Ruft nun ein Administrator die Kommentare-Seite im Backend auf (/contao/main.php?do=comments), so wird anstatt der Benutzer-IP der eingefügte Inhalt angezeigt. HTML und JS-Code kann somit permanent in das Backend eingefügt werden.

Empfehlung:

Um Cross-Site Scripting-Schwachstellen zu verhindern, sollten Benutzereingaben auch nach einer späteren Verarbeitung ausschließlich HTML-kodiert ausgegeben werden. Zur Erledigung dieser Aufgabe existieren bereits für die gängigen Programmiersprachen entsprechende Funktionen. In PHP existieren die Funktionen „htmlentities()“ oder „htmlspecialchars()“. Bei beiden Funktionen gilt es zu beachten, dass der zweite Parameter stets den Wert ENT_QUOTES und der dritte Parameter die eingesetzte Standard-Zeichensatz-Kodierung besitzt, z.B. „UTF-8“. Innerhalb von JavaScript-Blöcken sollten alle interpretierenden HTML-Metazeichen in ihre hexadezimale Notation übersetzt werden. Das hat u. a. auch zur Folge, dass der Internet Explorer keinen Code in diesem Kontext mehr ausführt. Dabei sollte jedoch beachtet werden, dass anschließend kein eval() ausgeführt wird. Beispiele für die hexadezimale Notation:

? Einfaches Hochkomma, ' ? \x27 oder \u0027
? Hochkomma, " ? \x22 oder \u0022
? Linke spitze Klammer, < ? \x3c oder \u003c

Beispiel:

```
$inhalt = htmlspecialchars($inhalt, ENT_QUOTES, 'UTF-8');
```

--- _Originally created by majorsecurity on December 24th, 2010, at 03:32pm (ID 2751)_