Sven Rautenberg: Gästebuch auf Angreifbarkeit testen

Beitrag lesen

Moin!

http://www.romy-b.de/guestbook_ausw.txt

Sieht übel aus.

  
// Inhalt  
$inhalt = $_POST["inhalt"];  
$inhalt=mysql_real_escape_string($inhalt);  
$inhalt=htmlentities($inhalt);  
$inhalt=nl2br($inhalt);  
// echo chunk_split(bin2hex($_POST["inhalt"]), 2, ' '); // zeigt die hex-Darstellung an  
if(strlen($inhalt)>2000 || strlen($inhalt)<1 ) {  
$fehler=1;  
$fehlerort="Inhalt";  
}  

Zuerst escapest du für die Datenbank. Dann machst du HTML-Entities rein. Und dann wandelst du Zeilenumbrüche in BRs.

Diese Vorgehensweise ist aus mehreren Gründen nicht gut:
1. Das Escapen für die Datenbank sollte grundsätzlich immer der allerletzte Schritt sein und dann stattfinden, wenn der SQL-String generiert wird. Ansonsten könnte es dir passieren, dass das Escapen durch die nachfolgenden Bearbeitungsschritte wieder rückgängig gemacht werden könnte, oder dadurch Zeichen eingeschleppt werden, die wiederum zu escapen wären.

2. Die vom Formular abgeschickten Daten sollten möglichst nicht vor dem Speichern in der Datenbank schon auf eines der möglichen Ausgabeformate gewandelt werden. Denn damit provozierst du die Notwendigkeit, die hier angewendeten Funktionen eventuell rückgängig machen zu müssen, wenn die Anforderungen an deine Ausgabe sich mal verändern. PHP bietet komfortabel Funktionen zum Wandeln von HTML-Zeichen in Entities oder nl2br - die Umkehrfunktionen existieren aber nicht, sondern müßten relativ aufwendig selbst erstellt werden. Deshalb als Faustregel: Daten immer so roh speichern, wie es geht, ohne sie schon für ein ganz spezielles Ausgabeformat zu konvertieren. htmlentities() und nl2br() lassen sich auch bei der Ausgabe noch simpel anwenden.

Weiter unten in deinem Code ist es sogar noch schrecklicher, da kommt nl2br() vor htmlentities() - das gibt mit Sicherheit Müll.

3. Deine Prüfung auf Einhaltung der von dir gewählten Einschränkungen findet erst nach diesen ganzen Wandlungen statt. Durch die vorhergehenden Funktionen ist der ursprünglich genau 2000 Zeichen lange String eventuell länger geworden - nämlich dann, wenn er Zeichen enthält, die escapte werden, in Entities gewandelt worden oder Zeilenumbrüche sind. Ein einziges doppeltes Anführungszeichen wird durch diese Vorgehensweise in 7 Zeichen gewandelt (Ergebnis: /&quot;).

4. Du prüfst nicht, ob der Eingangsstring aus $_POST eventuell durch magic_quotes_gpc schon Escape-Zeichen enthält und deshalb evtl. mit stripslashes() behandelt werden muß, bevor er in die weitere Verarbeitung geht. Diese Einstellung fragst du am besten zentral einmal mit ini_get('magic_quotes_gpc') ab und wendest stripslashes() dann jeweils lokal an.

Und zu guter letzt: Ich würde das Affenformular nicht mit einer Session realisieren. Das ist für diese simple Aufgabe einfach zuviel Technikkrams. Insbesondere, weil das Vorausfüllen eines fehlerhaft ausgefüllten Formulars nur dann funktioniert, wenn der Benutzer Cookies akzeptiert - das Fallback auf die Session-ID-Übermittlung per URL und/oder Formular hast du ja nicht mit eingebaut.

Hinsichtlich deiner Einschränkungen an EMail-Adresse und URL möchte ich anmerken, dass die längstmögliche Domain 63 Zeichen lang ist, eine URL ist grundsätzlich unbegrenzt lang. Aber die hat gewisse Formerfordernisse wie z.B. Protokollangabe ("http:", "ftp:", "mailto:"), Domain und Pfad.

  • Sven Rautenberg