Ein kurzer Ausflug in die PHP-Programmierung brachte mich heute auf einen Fehler, der mir hoffentlich früher auch nicht unentdeckt blieb. Aufgabe war es, die Einträge des Gästebuchs eines Kunden auf verschiedene Seiten auszugeben -- je nach Anzahl der Einträge pro Seite. Der englische Fachausdruck dafür ist Pagination.
Die Seitenzahl (bzw. das daraus errechnete Offset) wird über eine GET-Variable 'page' übergeben. Funktionierte alles wunderbar und schlußendlich wollte ich noch eine zusätzliche Prüfung auf schadhaften Code (SQL-Injection etc.) einbauen. Dieser Code soll prüfen, ob sich in $_GET['page'] auch wirklich nur Ziffern finden.
<?php
if(isset($_GET['page']) && !preg_match("/[0-9]+/", $_GET['page']))
die("Die Seitenzahl darf nur aus Ziffern bestehen.");
?>
Das funktioniert prinzipiell auch wie es sollte, bis ich einige Real-Life-Tests durchführte. Zwar stirbt das Script bei Werten wie '?page=ABC' wie gewünscht ab, sobald sich aber irgendwo eine Ziffer befindet -- '?page=AB123' -- nicht.
Der Fehler liegt im Detail, der richtige Ausdruck lautet nicht "/[0-9]+/" sondern "/^[0-9]+$/". Das Dach- und Dollar-Symbol stellt sicher, dass sich von Anfang bis Ende auch wirklich nur Ziffern befinden dürfen.
So funktioniert alles wie es sein soll und es gilt wieder einmal: Traue keiner Variable, die du nicht selbst definierst. Darüber hinaus dürfen die Funktionen addslashes, is_numeric respektive is_int und mysql_escape_string nicht unerwähnt bleiben.