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

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.

1
2
3
4
<?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.

Geschrieben am: 14. Aug. 2007 um 15:02 Uhr, Abgelegt in Computer & Webentwicklung

Kommentare zu diesem Artikel (1):

  1. Garvin schrieb am 15. August 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. Smiley:  :)

Kommentar schreiben

Kommentar hinzufügen

Neue Kommentare sind nur noch über diese Seite möglich.