Ich weiß, für viele ist das Thema ein alter Hut, aber wenn man so im weltweiten Netz unterwegs ist, findet man immer noch viel zu häufig Seiten auf denen die Problematik weiterhin existiert. Darunter sind auch durchaus bekannt und renommierte Sites. Es war z.B. vor gar nicht allzu langer Zeit selbst noch bei eBay möglich injizierten Code dafür zu missbrauchen um Auktionen und Bewertungen zu manipulieren und so ein Falsches Bild zu suggerieren (siehe z.B. diesen Heise-Artikel).
Hier möchte ich einmal die Grundlagen dafür schaffen, dass eine einfache HTML-Injektion auf euren Seiten nicht mehr möglich ist.
Das Problem
Versucht einfach mal auf diversen Internetseiten in ein Input-Suchfeld z.B. den folgenden Text (ohne die Anführungszeichen) einzugeben. „<script type=”text/javascript”>alert(“Hallo”);</script>“. Ihr werdet feststellen, dass auf einigen Sites immer noch auf der Folgeseite, welche die Eingabe auswertet z.B. steht „Ihre Suche nach ‚‘ liefert folgendes Ergebnis:“. Zusätzlich erscheint dann eine JavaScript Message-Box in der „Hallo“ steht. An diesem kleinen Beispiel könnt Ihr schon sehen wie sich das Problem schon bei so scheinbar kleinen Dingen deutlich macht.
Aber was ist eigentlich passiert … Ganz einfach, der HTML/PHP-Code auf der Seite, welche die Inputfelder auswertet, verarbeitet und wieder anzeigt, sieht voraussichtlich so, oder so ähnlich aus, wobei ich mal annehme, dass unser Suchwort nach dem Auslesen der Parameter in $kw steht.:
<span>Ihre Suche nach ‚<?php echo($kw);?>‘ liefert folgendes Ergebnis:</span>
Was hier passier könnt Ihr Euch vielleicht schon denken. Unser eingegebener Text, welcher wie Ihr bestimmt schon festgestellt habt reiner JavaScript-Code ist, wird hier einfach während der Generierung der auszuliefernden HTML-Seite ins HTML geschrieben. Vielleicht wird das Problem deutlicher, wenn wir uns einmal den generierten HTML-Code ansehen:
<span>Ihre Suche nach „<script type="text/javascript"> alert("Hallo"); </script> ‘ liefert folgendes Ergebnis:</span>
Hier wird wohl jedem das Problem klar. Der Browser interpretiert natürlich den Script-Teil als JavaScript und führt in anstandslos und vollkommen berechtigt aus. Das Problem liegt auch in keiner Weise beim Browser auf der Client-Seite vor, sondern schon serverseitig.
Jetzt werden sogar einige noch sagen – „Na und? Soll doch die eine Seite für den einen User, der den Output bekommt so aussehen. Wenn er Spaß daran hat.“. Aber natürlich weit gefehlt, Stellt Euch einfach vor, euer in dem Input-Feld eingegebener Text diente nicht zur Suche, sondern dazu einen Kommentar in einem Blog, oder auf einer News-Seite zu hinterlassen. Sind diese Kommentare dann nicht moderiert, sondern gehen sofort Online, dann sehen alle nachfolgenden User die manipulierte HTML-Seite und die Infiltrierung ist permanent. Da kann dann Gott weiß was für ein Javascript und/oder CSS zur Manipulation dienen und ggf. die ganze Seite veränder und sogar redirecten zu einer anderen.
Die Lösung
Aber was machen wir nun dagegen und wie verhindern wir das? Was hier technisch passieren muss, ist, dass Ihr den HTML-Code als HTML-Entities ausgeben müsst. Der ggf. mit den Parametern eingeschleuster HTML-Code muss quasi maskiert werden, so dass der Interpreter, welcher den HTML-Code interpretiert später nicht als HTML sieht. Das < Zeichen wird hier z.B. zu < und das > Zeichen zu >. PHP liefert hier zum Glück schon Bordmittel, mit welchen wir der Sache Herr werden. Die Methode, welche hier zu zum Einsatz kommt heißt htmlentities. Der richtige PHP-Schnipsel würde also so aussehen:
<span> Ihre Suche nach ‚<?php echo(htmlentities($kw, ENT_QUOTES));?>‘ liefert folgendes Ergebnis:</span>
Der Parameter ENT_QUOTES ist hier übrigens besondern wichtig, da sonst leider keine Anführungsstriche maskiert werden. Das ist ein kleiner Nachteil von der Methode. Dann würde der generierte HTML-Code beim User wie gewünscht so aussehen. Wohlbemerkt der Quellcode und nicht der im Browser Sichtbare Teil:
<span> Ihre Suche nach „<script type="text/javascript"> alert("Hallo"); </script> ‘ liefert folgendes Ergebnis</span>
Jetzt wird unser eingegebener Text aus $kw wirklich als Text behandelt und nicht als HTML interpretiert. Diese Maskierungs-Methode mittels htmlentities sollte überall da angewendet werden, wo in irgendeiner Weise unbekannter Inhalt ausgegeben wird, den Ihr selbst nicht unter Kontrolle habt. Das währen z.B. Cookie-Inhalte, DB-Inhalte oder halt Paramter-Werte. Achtet auf jeden Fall auch darauf, diese Methode auch bei Values in Input-Feldern und Textareas anzuwenden.
Keine trügerischen Gegebenheiten voraussetzen
Geht auch nie davon aus, dass Ihr den Inhalt per JavaScript abfangt, oder die Werte in Hidden-Fields standen. Denkt immer daran, dass alles manipulierbar ist.
- Javascript könnte deaktiviert sein
- Der komplette Query-String des Request könnte einfach kopiert und danach manipuliert und händlisch noch mal gesendet werden.
- Hidden-Fields lassen sich kinderleicht mit heutigen Mitteln wie dem Firebug im Firefox einfach vor dem Submit manipulieren.
- und … und … und
Codierung der Seite beachten
Falls Ihr übrigens eure Seite nicht in ISO-8895-1, sondern z.B. in UTF-8 codiert habt, dann solltet Ihr besser die Methode wie folgt aufrufen:
htmlentities($kw, ENT_QUOTES, 'utf-8');
Das sorgt für eine richtige Codierung in UTF-8
Eine nicht wirklich gute Alternative
Es existiert im übrigen auch noch eine zweite Methode in PHP, welche zum maskieren denkbar wäre. Sie lautet htmlspecialchars und arbeitet eigentlich genau wie htmlentities, allerdings wandelt diese Methode nicht alle Zeichen, die eine HTML-Code-Entsprechung haben um. Umgewandelt werden nur das Ampersand (&), doppelte und einfache Anführungszeichen, das „kleiner als“-Zeichen (<) und das“ größer als“-Zeichen(>). Das ist schon desshalb wie ich finde in der heutigen Zeit obsolet, weil z.B. nicht encodierte Umlaute zu HTML-Validierungs-Fehlern führen.
100%ige Sicherheit ist schwer
Wer jetzt denkt, er wäre hiermit immer auf der sicheren Seite, der sollte einmal dieses Popup aufrufen. Dann klickt den Link im Popup und wundert Euch. Hier ist übrigens der PHP-Code des Popups. Eigentlich sollt htmlentities das Gesehene doch verhindern
!? Fühlt Euch also nie zu sicher.
<?php $xssValue = "javascript:alert(String.fromCharCode(83, 105, 99, 104, 101, 114, 104, 101, 105, 116, 160, 105, 115, 116, 160, 73, 108, 108, 117, 115, 105, 111, 110)) "; ?> <a href="<?php echo(htmlentities($xssValue, ENT_QUOTES));?>">htmlentities ist 100%ig sicher</a>
Ähnliche Artikel:






Kommentare