Was man bei Eingabe-Prüfung falsch machen kann (u.a. SQL-Injection)

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.


  • Garvin Aug. 15, 2007

    Was übrigens noch sicherer ist, ist die Benutzung von

    $sql = "SELECT ... LIMIT " . (int)$_REQUEST['page'];

    Durch das (int) forciert man, dass eine Variable in einen Integer umgewandelt wird. Ungültige Zeichen prodzieren dann den Integer "0". Das spart Dir einen preg_match()-Aufruf und damit auch etwas Performance. :)


Comments closed

Sorry, new comments are no longer allowed for this entry.

Write me an email if you have feedback or any questions regarding this post. If you found this post useful and just want to say thank you then don't forget that I have an Amazon Wishlist. :-)


↑ to the elevators

© 2001—2010 Martin Mahner. This is an I ♥ Django Project.

Admin | Generated: Wed, 1 Sep 2010 12:20:00 +0200