Hallo
Es soll eine PHP Applikation erstellt werden, dafür habe ich mir nun zuerst einige Gedanken zur Sicherheit und zur Validierung der Eingabedaten gemacht. Die Anwendung soll u.a. einen Userbereich mit einem Anmeldeformular für selbigen enthalten.
Ich möchte folgendermaßen vorgehen:
(Auf dem Entwicklungs- als auch auf dem Zielserver ist magic_quotes_gpc = off)
1) Formulareingaben werden entsprechend des erwarteten Typs geprüft:
- Name: preg_match("/^[a-zA-ZÄÖÜßäöüéèêáàâ&-.\s]$/", $_POST['name']);
- Email: preg_match("/^[A-Z0-9._%+-ÄÖÜäöü]+@[A-Z0-9.-ÄÖÜäöü]+\.[A-Z]{2,6}$/i", $_POST['mail'])
- URL: preg_match("/^(http|https)\:\/\/[a-z0-9-.\/]$/i", $_POST['url'])
- Passwort: Die Speicherung würde als MD5 Hash erfolgen: md5($_POST['password'].$salt)
Hier möchte ich im Prinzip alle erdenklichen Zeichen zulassen, fürchte nur, daß es irgendwelche bösen Zeichen gibt, mit denen ich mir möglicherweise ein Loch ins Script reiße (Beispiel siehe [1]). So gesehen ist es vielleicht sinnvoller, das Passwort auch auf den Zeichenvorrat des Namens einzuschränken.
- Textfeld: preg_match("/^[a-zA-Z0-9-ÄÖÜßäöü.,:!?\s\r\n]$/", $_POST['text'])
Ist es notwendig, vor der Validierung mit preg_match() die Funktion strip_tags() anzuwenden?
2) Wenn die unter 1) genannte Validierung fehlschlägt, wird das Formular erneut mit den bereits eingetragenen, möglicherweise bösen Werten angezeigt. Diese werden vor der Ausgabe noch einmal mit htmlentities() bearbeitet.
3) Wenn alle Eingaben den regulären Ausdrücken entsprechen, werden die Daten in eine MySQL Datenbank eingetragen. Dazu nutze ich die unter [2] genannte erweiterte mysqli Klasse, welche mit Prepared Statements arbeitet.
Bin ich hier wirklich sicher vor SQL Injections oder kann es unter irgendwelchen Umständen trotzdem dazu kommen, so daß weiterhin mit mysql(i)_real_escape_string gearbeitet werden sollte?
4) Ist es ein Risiko, strtolower() auf eine ungeprüfte Variable anzuwenden? Gleiches wäre interessant für die Verarbeitung einer ungeprüften Variable in einer switch/case Anweisung.
5) Ebenso könnte über die superglobale Variable $_SERVER unerwünschter Input eingeschleust werden. Genügt es hier, beispielsweise für den Useragent, addslashes($_SERVER['USER_AGENT']) anzuwenden oder reicht das nicht bzw. wäre eine andere Funktion sinnvoller? Kann auch $_SERVER['REMOTE_ADDR'] gefakt werden und sollte daher erst validiert werden?
Erstmal vielen Dank an alle, die dieses lange Posting bis hier durchgelesen haben
Ich bin für sinnvolle Tips, Anregungen und Ergängzungen zu der beschriebenen Vorgehensweise sowie für die Beantwortung der gestellten Fragen dankbar. Wenn jemand ein sicherheitstechnisches "Problem" entdeckt, beispielsweise ein fälschlicherweise zugelassenes böses Zeichen in einem der regulären Ausdrücke, bin ich ebenfalls für einen Hinweis dankbar.
[1] http://www.phpbb.de/community/viewtopic.php?t=110637
[2] http://www.robpoyntz.com/blog/?p=191
Es soll eine PHP Applikation erstellt werden, dafür habe ich mir nun zuerst einige Gedanken zur Sicherheit und zur Validierung der Eingabedaten gemacht. Die Anwendung soll u.a. einen Userbereich mit einem Anmeldeformular für selbigen enthalten.
Ich möchte folgendermaßen vorgehen:
(Auf dem Entwicklungs- als auch auf dem Zielserver ist magic_quotes_gpc = off)
1) Formulareingaben werden entsprechend des erwarteten Typs geprüft:
- Name: preg_match("/^[a-zA-ZÄÖÜßäöüéèêáàâ&-.\s]$/", $_POST['name']);
- Email: preg_match("/^[A-Z0-9._%+-ÄÖÜäöü]+@[A-Z0-9.-ÄÖÜäöü]+\.[A-Z]{2,6}$/i", $_POST['mail'])
- URL: preg_match("/^(http|https)\:\/\/[a-z0-9-.\/]$/i", $_POST['url'])
- Passwort: Die Speicherung würde als MD5 Hash erfolgen: md5($_POST['password'].$salt)
Hier möchte ich im Prinzip alle erdenklichen Zeichen zulassen, fürchte nur, daß es irgendwelche bösen Zeichen gibt, mit denen ich mir möglicherweise ein Loch ins Script reiße (Beispiel siehe [1]). So gesehen ist es vielleicht sinnvoller, das Passwort auch auf den Zeichenvorrat des Namens einzuschränken.
- Textfeld: preg_match("/^[a-zA-Z0-9-ÄÖÜßäöü.,:!?\s\r\n]$/", $_POST['text'])
Ist es notwendig, vor der Validierung mit preg_match() die Funktion strip_tags() anzuwenden?
2) Wenn die unter 1) genannte Validierung fehlschlägt, wird das Formular erneut mit den bereits eingetragenen, möglicherweise bösen Werten angezeigt. Diese werden vor der Ausgabe noch einmal mit htmlentities() bearbeitet.
3) Wenn alle Eingaben den regulären Ausdrücken entsprechen, werden die Daten in eine MySQL Datenbank eingetragen. Dazu nutze ich die unter [2] genannte erweiterte mysqli Klasse, welche mit Prepared Statements arbeitet.
Bin ich hier wirklich sicher vor SQL Injections oder kann es unter irgendwelchen Umständen trotzdem dazu kommen, so daß weiterhin mit mysql(i)_real_escape_string gearbeitet werden sollte?
4) Ist es ein Risiko, strtolower() auf eine ungeprüfte Variable anzuwenden? Gleiches wäre interessant für die Verarbeitung einer ungeprüften Variable in einer switch/case Anweisung.
5) Ebenso könnte über die superglobale Variable $_SERVER unerwünschter Input eingeschleust werden. Genügt es hier, beispielsweise für den Useragent, addslashes($_SERVER['USER_AGENT']) anzuwenden oder reicht das nicht bzw. wäre eine andere Funktion sinnvoller? Kann auch $_SERVER['REMOTE_ADDR'] gefakt werden und sollte daher erst validiert werden?
Erstmal vielen Dank an alle, die dieses lange Posting bis hier durchgelesen haben
Ich bin für sinnvolle Tips, Anregungen und Ergängzungen zu der beschriebenen Vorgehensweise sowie für die Beantwortung der gestellten Fragen dankbar. Wenn jemand ein sicherheitstechnisches "Problem" entdeckt, beispielsweise ein fälschlicherweise zugelassenes böses Zeichen in einem der regulären Ausdrücke, bin ich ebenfalls für einen Hinweis dankbar.
[1] http://www.phpbb.de/community/viewtopic.php?t=110637
[2] http://www.robpoyntz.com/blog/?p=191
Kommentar