Sicherheit Javascript ausschließen mit PHP
Es kommt immer wieder vor, dass in Websites unerlaubtes Javascript eingeschmuggelt wird. Um einen Text mit Javascript auszuschließen, müssen eine Reihe von Möglichkeiten beachtet werden. Diese sogenannten XSS-Attacken (cross side scripting) können viel anrichten, zum Beispiel indem Paßwörter durch gefälschte Formulare abgefangen werden. Gelingt es, den Code in der Datenbank zu speichern, kann er als regelrechter Virus genutzt werden und weitere Änderungen vornehmen.
Mit den Zeichen >, <, " und ' kann HTML auf einer Website verändert werden. Werden diese Zeichen in Entities umgewandelt, also >, <, " und ', ist die Gefahr weitgehend behoben. Alternativ können diese Zeichen auch aus allen Benutzereingaben gelöscht werden.
Es reicht nicht, > und < umwandeln. In der Website kann es vorkommen, dass Inhalte von Benutzern auch innerhalb von HTML-Tags ausgegeben werden. Je nachdem, wie das HTML aufgebaut ist, können ohne Zeichenumwandlung HTML-Attribute wie onload oder onclick (Events) eingeschleust werden.
Beispiele, wie es nicht gemacht werden soll:
Ungefiltert kann hier in mehreren Versionen Code eingeschleust werden:
<?php
echo '<a href="search.php?search='
.$_GET['search']
.'">Suche</a>';
?>
Damit bieten sich dem Angreifer mehrere Möglichkeiten, Javascript einzuschleusen:
<a href="search.php?search="><script>alert ('Angriff!');</script>">Suche</a>
<a href="search.php?search=" onclick="alert ('Angriff!');">Suche</a>
Für Angriffe besonders anfällig sind <input>- und <textarea>-Elememte, da bei falscher Eingabe die Benutzereingaben gerne wieder ausgegeben werden.
Ein Lösungsansatz
Der Lösungsansatz gilt nicht für Bereiche, wo der Anwender HTML abspeichern darf. HTML muss anders überprüft werden!
Viele Wege führen nach Rom, darum will ich erstmal einen Lösungsansatz vorstellen. Auf öffentlichen Seiten filter ich mit einer Klasse alle REQUEST-Parameter, indem ich die Zeichen >, <, " und ' mit >, <, " und ' ersetze, und zwar in $_REQUEST, $_POST und $_GET. Alternativ kann ich auch die Zeichen mit Leerzeichen ersetzen.
Ich kann dann diese globalen Variablen wie bisher weiter benutzen, muss aber beachten, wo ich die Quelle benötige. Ob ich die veränderten Werte in die Datenbank speichere, hängt davon ab, wie sie weiter verarbeitet werden sollen. ‘Mustermann & Söhne’ ist nicht das gleiche wie ‘Mustermann & Söhne’ und beeinflußt Suchergebnisse. Falls die Daten später wieder auf der Website dargestellt werden sollen, müssen sie auch erneut umgewandelt werden. Passwörter sollten nie gefiltert gespeichert werden.
Um auf die ungefilterten REQUESTs zugreifen zu können, speichere ich mir eine Kopie ab.
Mit diesem Code mit Anwendungsbeispiel können ohne viel Aufwand spezielle Filter erstellt werden. Der Code steht unter MIT-Lizenz (Open Source).
Andere Risiken
Es gibt noch diverse Risiken, die über REQUESTs auftreten können. Grundsätzlich sollten alle REQUESTs auch inhaltlich überprüft werden.
Besonders anfällig sind dabei E-Mail-Parameter – insbesondere Betreff und E-Mailadresse -, Datei- und Verzeichnispfade, SQL-Queries und andere Speicherformate und Systemaufrufe.
Quellen
- Wikipedia zu Cross-Site Scripting
- Offizielle PHP-Infos zu register_globals
- www.cms-sicherheit.de bietet einen guten Überblick über Sicherheitsrisiken und Lösungen.
- Sicherheiterweiterung Suhosin für PHP
- mod_security für Apache
2 Kommentare
Harald vom 2008.10.25 , 18:27 Uhr
Wenn ich nur die Specialchars verarbeiten würde, hättest du sicher recht. Die Klasse HakaArrayConvertChars ersetzt aber weitere Zeichen wie die meisten im ASCII-Bereich 0-32 und soll die Möglichkeit bieten, die Specialchars zum Beispiel durch Leerzeichen zu ersetzen.

Web CMS vom 2008.10.23 , 21:23 Uhr