Squirrelmail: Cross-Site-Scripting bei Verarbeiten von MIME-Daten und weitere Lücken

Squirrelmail ist eine in PHP programmierte Weboberfläche für E-Mail-Kommunikation. Die Software benötigt lediglich PHP auf dem Webserver und lässt sich über verschiedene Plugins erweitert werden. Aufgrund eines Programmierfehlers in den Routinen zum Verarbeiten von HTML-MIME-Daten ist ein entfernter Angreifer in der Lage, Cross-Site-Scripting-Attacken gegen Squirrelmail durchzuführen.

Die Schwachstelle befindet sich in der Datei “functions/mime.php”, wo die Funktion “sq_sanitize()” dafür zuständig ist, einen übergebenen HTML-String zu filtern. Am Ende liefert sie geprüften HTML-Code zurück, der ohne Bedenken angezeigt werden kann, weil sicherheitskritische Benutzereingaben entfernt sind. Dieser vertrauenswürdige HTML-Code wird in der Funktion unter der Variable “$trusted” zusammengebaut. Die Funktion “sq_sanitize()” selbst wird von der “magicHTML()”-Funktion (ebenfalls in “mime.php”) aufgerufen.

Hier werden auch die folgenden Variablen gesetzt, die das genaue HTML-Filterverhalten von “sq_sanitize()” spezifizieren: “rm_tags_with_content”, “self_closing_tags”, “force_tag_closingm”, “rm_attnames”, “bad_attvals”, “add_attr_to_tag”. Die Funktion “sq_sanitize()” läuft in einer While-Schleife über die einzelnen HTML-Tags und analysiert diese mit der Funktion “sq_getnxtag()” die in einem Array (“Array($tagname, $attary, $tagtype, $lt, $pos)”) unter anderem die etwaigen Attribute des entsprechenden Tags in “$attary” zurückliefert. Die Schleife behandelt basierend auf diesem Rückgabewert die verschiedenen Tags, wobei speziell für das Style-Tag folgender PHP-Code abgearbeitet wird:

if ($tagname == "style" && $tagtype == 1){ list($free_content, $curpos) = sq_fixstyle($body, $gt+1, $message, $id, $mailbox); if ($free_content != FALSE){ $trusted .= sq_tagprint($tagname, $attary, $tagtype); $trusted .= $free_content; $trusted .= sq_tagprint($tagname, false, 2); } continue; }

Hier ist zu erkennen, wie die Variable “$trusted” durch PHPs String Concatenation (den Punkt-Operator) sukzessive zusammengesetzt wird. Die hier aufgerufene Funktion “sq_tagprint()” bastelt basierend auf dem Tag-Namen und den übergebenen Tag-Attributen einen gültigen HTML-Eintrag für das Element zusammen:

function sq_tagprint($tagname, $attary, $tagtype){ $me = 'sq_tagprint'; if ($tagtype == 2){ $fulltag = '</' . $tagname . '>'; } else { $fulltag = '<' . $tagname; if (is_array($attary) && sizeof($attary)){ $atts = Array(); while (list($attname, $attvalue) = each($attary)){ array_push($atts, "$attname=$attvalue"); } $fulltag .= ' ' . join(" ", $atts); } if ($tagtype == 3){ $fulltag .= ' /'; } $fulltag .= '>'; } return $fulltag;
}

Deutlich zu erkennen sind hier die HTML-typischen spitzen Klammern. Ausser ein paar grundlegenden Tests zur Länge der Attribute werden die Attribute in “$attary” allerdings keinen weitereen Prüfungen unterzogen. Das heißt, der von “sq_getnxtag()” zurückgelieferte “$attary”-Eintrag wird direkt zur Konstruktion des später angezeigten HTML-Codes verwendet.

Dadurch kann ein entfernter Angreifer eine HTML-Nachrichten mit entsprechendem Style-Tag-Attribut an sein Opfer senden, um damit Javascript- oder HTML-Anweisungen auszuführen. Diese Anweisungen werden im Browser des Opfers ausgeführt, und für den Anwender sieht es so aus, als kämen sie von der Squirrelmail-Seite.

In der Datei “mime.php” findet sich allerdings eine Funktion, die genau das verhindern soll: “sq_fixatts()”. Wie der Name schon andeutet kümmert sich diese Funktion darum, dass keine schadhaften Attribute ihr Unwesen treiben. Es wurde also lediglich vergessen, diese auf “$attary” im Falle des Style-Tags anzuwenden. Das Patch für die Style-Tag-Schwachstelle holt dies nach:

if ($free_content != FALSE){ $attary = sq_fixatts($tagname, $attary, $rm_attnames, $bad_attvals, $add_attr_to_tag, $message, $id, $mailbox );
...

Damit kann ein Angreifer mit speziellen Style-Attributen keinen Schaden mehr Anrichten. Der Fehler wurde am 12. Juli 2011 im Repository korrigiert, Betroffen ist die Squirrelmail-Version 1.4.21 und ältere.

In diesen Versionen wurden auch einige weitere Sicherheitslecks entdeckt, wobei es sich meist um Cross-Site-Skripting-Schwachstellen handelt. Eine davon befindet sich in dem Rechtschreib-Plugin in der Datei “modules/check_me.mod”. Hier kommt die Funktion “chop()” zum Einsatz, um kritische Zeichen aus Strings zu entfernen:

. chop(addcslashes($sqspell_lines[$i], "'\"\\\x0")) . "\";\n";

Allerdings wurde dabei vergessen, auch schließende Spitzklammern zu entfernen, wodurch ein Angreifer Cross-Site-Scripting-Code einschleusen kann. Der korrekte chop-Aufruf mit erweitertem Filtersatz sieht so aus:

. chop(addcslashes($sqspell_lines[$i], ">'\"\\\x0")) . "\";\n";
Nach oben