PHP XSS (Cross Site Scripting) Problem

godofkills

Lt. Commander
Registriert
Dez. 2009
Beiträge
1.997
Hallo,
ich habe auf meiner Seite eine Kommentar Funktion.
Nun hab ich gemerkt das per XSS (Cross Site Scripting) meine Seite leicht zu verunstalten ist. Nun wollte ich gerne wissen was die beste Möglichkeit ist das zu verhindern. Ich hab paar Sachen ausprobiert und es war erschreckend was alles möglich ist mit diesen Befehlen.
Wisst ihr da eine Lösung?
 
Vielen dank. Warum wird das nicht schon von Haus aus geblockt? Oder ist es gewollt durch ein textfeld fremd Code auszuführen?
 
Du solltest dir angewöhnen, $_POST und $_GET immer zu validieren. Außerdem ist es nicht immer ein gewünschtes Verhalten, diese bestimmten Sonderzeichen in HTML-Code umzuwandeln. Aus diesem Grund wird es auch nicht von Haus aus "geblockt".
 
Ja ich hab meine Seite jetzt bearbeitet. Nun werden alle validiert.
 
ich kann dir empfehlen nicht direkt auf $_GET oder $_POST zuzugreifen, sondern immer über ne Wrapper-Klasse der du den gewünschten Typ als Argument übergibst.
Für die Ausgabe (also das was im Browser angezeigt wird) solltest du ähnliche Mittel verwenden. XSS betrifft nicht nur Textfelder, sondern jegliche Daten die direkt oder indirekt (z.B. über die Datenbank) in der HTML-Ausgabe landen.

z.B. http://blablabla.com/index.php?id=1 kann schnell zu http://blablabla.com/index.php?id=<script ...></script> verunstaltet werden. Wenn du den Wert einfach über echo $_GET['id'] oder vergleichbares in deinen HTML-Code ausgibst kann das schnell hässlich werden!
 
Hey,

htmlentities() und strip_tags() können im bestenfall gegen Scriptkiddys helfen, wie das nachfolgende Workarround zeigt.
Zur Zeit sollte man wirklich über eine Whitelist filtern, vielleicht sogar "eval" und "fromCharCode" verbieten.


PHP:
// Aufruf: Xss.php?homepage=javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41)) 

<html>
<a href="<?php echo strip_tags(htmlentities($_GET['homepage'])); ?>">Link</a>
</html>
 
Also wenn ich das hier versuche:
[xURL=javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))]test[/xURL] (natürlich ohne die "x")

kommt der Link raus:
test

passiert bei mir relativ wenig... ist interessant, was hier beim Forum damit passiert...

Und naja, man muss bei jedem Parameter vorsichtig sein den man so handhabt wie in diesem Extrem-Beispiel, ich würde z.B. nie einen solchen Parameter einfach als URL in einen Link reinmachen, höchstens als Zusatz - und da ist dann wieder die Angriffsfläche geringer... Und was für Möglichkeiten hat man bei einem solchen Angriff? Also welche Art Schaden kann man den konkret anrichten? Nen JavaScript-Alert beunruhigt mich jetzt wenig...

Edit:
Ok geht um Verunstaltung, dann klar... aber ich frag mich wie gesagt warum man einen vom User eingegebenen Parameter überhaupt so auf die Seite bringen soll...
Wenn ich ne URL erwarte weiß ich dass das Ding mit http:// oder https:// anfangen sollte... tut es das nicht mach ich's selbst hin oder verweigere die Eingabe direkt - Problem gelöst... Bei ner E-Mail-Adresse wird beim Link eh nen mailto: drangesetzt usw...

Whitelist? Wenn du damit eben die von mir dargestellte Prüfung meinst gerne... ansonsten ist es nicht leicht zu sagen, was alles erlaubt ist - noch schwerer im Übrigen, was alles nicht erlaubt ist...

Die einfachste Lösung wäre, von User eingegebene Inhalte nicht auf solch hirnlose Weise auszugeben...
 
Zuletzt bearbeitet:
Naja, also ich würde Verunstaltung jetzt mal als das kleinere Übel sehen, genauso gut könnte man mit JavaScript Cookies stehlen (eig. Standard bei XSS), einen automatischen Redirect einbauen (Thema Drive-By-Infection), einen Keylogger aktivieren, ...

Es gibt ne ganze Menge, was man mit JavaScript machen kann, das sollte man auf keinen Fall unterschätzen.

@Yuri_Orlov: Strip Tags würd ich auch nicht verwenden, da stimm ich dir schon zu, aber man muss die Dinge schon ein wenig in einem Kontext sehen. Natürlich wird mir hier htmlentities nicht viel bringen, wenn ich nirgendwo HTML Code zum validieren habe. Wenn ich dem Angreifer direkt die Möglichkeit lasse, so JavascriptCode auszuführen, kann ich auch gleich alles in einen <script> Tag setzen ;)
Was ich damit sagen kann: Natürlich kann es solche Szenarien geben, aber wenn man Abwehrmechanismen einsetzt, dann sollte man sich auch schon Bewusst sein, wie und wann sie wirken. Und in einem normalen und "realistischeren" Szenario ist htmlentities schon sehr ausreichend. (Wobei bei Eventhandlern auch wieder sehr vorsicht geboten ist)

Und wie würdest du eine Whitelist bei dynamisch generierten Seiten realisieren?

Und noch viel interessanter, wie würdest du eval und fromCharCode verbieten? Bedenke dabei allerdings sämtliche Codierungsmöglichkeiten und andere Tricks, mit denen man einfache Filter umgehen kann. Eine Blacklist würd ich eig. immer als letzte Möglichkeit ansehen, da es einfach zu viele Ansätze gibt, um selbst Multi-Stage Filter zu umgehen.

Übrigens, um dein Filtervorhaben gleich mal ad absurdum zu führen: Hast du deinen Seitenaufruf schon mal mit ?homepage=javascript:alert("XSS") probiert? ;)


so long
 
-=Renegade=- schrieb:
Und wie würdest du eine Whitelist bei dynamisch generierten Seiten realisieren?

In der Regel arbeiten dynamische Seiten mit Zahlen, daher reicht ein simples Typecasting um auf der sicheren Seite zu sein. Größere Module, wie bspw. ein Gästebuch-Modul etc., werden einfach in einer Datenbank registriert und somit ist ein dynamisches Hinzufügen gewährleistet.
 
@Trainmaster:
Sie arbeiten mit Zahlen als IDs weil sich diese halt leicht generieren lassen (und die Datenbank dies normal schon selbst macht), das hat nicht viel mit Sicherheit durch Typecasts zu tun. Schlussendlich wird dann geschaut, ob es zu entsprechender ID etwas aus der Datenbank gibt. Mit Whitelist hat sowas wenig zu tun. Eine Whitelist wäre für mich eher eine Art erlaubte HTML-Tags (nicht BBCode oder ähnliches), die nicht gefiltert werden...

(Außerdem sind das eh Dinge, die aus dem System selbst kommen, es handelt sich in keiner Form um dazustellende Nutzereingaben...)

@Renegade: Stimme dir da absolut zu...
 
Zuletzt bearbeitet:
Das Prinzip der Whitelist kann man ruhig etwas weiter auffassen. Eine Datenbank ist für mich nichts anderes als eine Liste vertrauenswürdiger Elemente. Dir geht es scheinbar darum, dass bei einer Whitelist grundsätzlich nicht gefiltert werden muss?

Aber vergessen wir für einen Moment die IDs. Oftmals werden auch einfache Strings übergeben, um dynamische Seiten abzurufen. In diesem Fall lässt sich das Whitelist-Prinzip sehr gut anwenden. Meiner Meinung nach lässt sich die Menge erlaubter Zeichen gerade bei $_GET-Parametern sehr gut bestimmen.

Über Spielerein wie
PHP:
?homepage=javascript:alert("XSS")
kann ich daher nur getrost lachen.
 
IceMatrix schrieb:
Für die Ausgabe (also das was im Browser angezeigt wird) solltest du ähnliche Mittel verwenden. XSS betrifft nicht nur Textfelder, sondern jegliche Daten die direkt oder indirekt (z.B. über die Datenbank) in der HTML-Ausgabe landen.
wenn man das noch generalisiert stimmt die Aussage ;)
Jedesmal wenn Daten an ein Subsystem übergeben werden (HTML-Ausgabe, Datenbank, Emails...) müssen die Daten für das Medium escaped werden.


PS.: Es soll sogar Bücher geben, die sich auf vielen Seiten mit der Sicherheit beschäftigen, setzt man noch das Wort PHP in den Titel und schaut nach einem Buch von Stefan Esser hat man auch sogleich ein richtig gutes Werk.
 
Trainmaster schrieb:
In der Regel arbeiten dynamische Seiten mit Zahlen, daher reicht ein simples Typecasting um auf der sicheren Seite zu sein. Größere Module, wie bspw. ein Gästebuch-Modul etc., werden einfach in einer Datenbank registriert und somit ist ein dynamisches Hinzufügen gewährleistet.

In der Regel würden solche Seiten wohl auch kein ?homepage=javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41)) erlauben und ein htmlentities würde ebenso, wie in diesem Spezialfall ein Typecasting, ausreichen.

Problematisch wird es also wohl auch dadurch, dass ich nicht davon ausgehen kann, dass die Seite von einem "professionellen" Programmierer entwickelt wurde, sondern einfach mal so eine 0815 Seite eines Hobbyentwicklers ist.

Das "Problem" einer Whitelist ist, dass ich immer ein Medium brauche. Natürlich kann ich gegen eine Datenbank validieren, ich kann auch gegen ein Filesystem validieren, ob die Datei existiert. Das trifft zum Beispiel hervorragend für das inkludieren anderer Seiten zu.

Trotzdem ist eine Whitelist kein universelles Einsatzmittel. Um auf das eigentliche Problem des TE zurückzukehren, nämlich eine Kommentarfunktion zu validieren, ist eine Whitelist einfach nicht Mittel der Wahl, sondern ein simples htmlentities. Und nur eine Whitelist zu verwenden, damit ich ein irrsinniges Konstrukt wie <a href="<?php echo strip_tags(htmlentities($_GET['homepage'])); ?>">Link</a> im Code stehen lassen kann, ist für mich auch keine Entscheidung.

so long
Renegade
 
Ich wollte mit diesem absolut praxisfremden Bsp. nur zeigen, wo genau die Schwächen bei den beiden PHP Funktionen htmlentities() und strip_tags() sind.

Mein Beitrag war als Zusatz zum Beitrag von 1668mib gemeint.
Ich wollte damit ausdrücken "Hey, die beiden im Link genannten Funktionen haben exploits!"
Natürlich macht mein Bsp. keinen Sinn für XSS....
Ergänzung ()

Renegade,

das BSI hatte hier mal einen Whitelist-Filter spezifiziert.

Für die Sicherheitsbibliothek SSEQ_LIB wurde die Funktion nach PHP portiert.
 
Zuletzt bearbeitet:
Yuri_Orlov schrieb:
Ich wollte mit diesem absolut praxisfremden Bsp. nur zeigen, wo genau die Schwächen bei den beiden PHP Funktionen htmlentities() und strip_tags() sind.

nein da ist nirgends eine Schwachstelle, ein htmlentites ist vollkommen ausreichend .
Wenn man solch einen Mist fabriziert und eine komplette URL auf Basis einer URL zusammenbaut ist das kein Problem der sicheren htmlentities-Escaping-Funktion sondern einfach nur ein absolut dämlicher Entwickler.
 
Zurück
Oben