Eine weit verbreitete Art dynamische Seiten mit PHP zu erstellen ist es Dateien über die PHP-Funktion include () in ein Seitengerüst einzubinden. Nicht selten bezieht man die Information, um welche Seite es sich denn nun handelt aus einer GET-Variable.
Das Problem ist allerdings folgendes: Überprüft man den zurückgegebenen Wert von z.B. $_REQUEST ['page'] nicht ordentlich, lassen sich beliebige Dateien in das Homepagegerüst einfügen.
Dazu ein Beispiel: Wahrend eine normale Seite über die URI „index.php?page=home.php“ und mit dem PHP-Code
include ($_REQUEST ['page'])
angezeigt wird, kann ein Angreifer mit index.php?page=/etc/passwd die Benutzerdatei eines Unix-Systems anzeigen.
Auch ein Pre- bzw. Suffix verhindert dies nicht unbedingt. Nehmen wir an, dass wir mit folgendem Code die Seiten einbinden:
include ('/my/home/dir/' . $_REQUEST ['page'] . '.php')
Dies kann auf einfache Art umgangen werden. Um in die nächsthöhere Verzeichnisebene zu gelangen muss man dem /etc/passwd einfach ein paar ../ voranstellen. Um nun die zweite Hürde, den Suffix .php, zu nehmen ist es nur nötig an ../etc/passwd ein %00 anzufügen und schon wird der .php-Suffix abgeschnitten. Dies funktioniert aber anscheinend nur mit älteren PHP-Versionen. (Wer in C programmiert kennt diesen Effekt sicherlich. Ein Null-Byte zeigt dort das Ende einer Zeichenkette an.) Der fertige Angriff ließe sich also mit index.php?page=../../../etc/passwd%00 ausführen.
Meine Lösung für das Problem wäre der reguläre Ausdruck \[^a-zA-Z0-9_-\], der Unerwünschtes recht zuverlässig filtert, aber natürlich auch die möglichen Datei- beziehungsweise Seitennamen einschränkt.
Eine weitere Möglichkeit diesen gefährlichen include-Befehl auch ohne Einschänkung der Seitennamen zu entschärfen wird bei den häufig gemachten Anfängerfehlern beschrieben.