Tutorials - einfache Schritte zur sicheren PHP-Programmierung
Sprachenübersicht/Programmierung/PHP/Security
einfache Schritte zur sicheren PHP-Programmierung
Diese Seite wurde 6049 mal aufgerufen.
Dieser Artikel wurde in einem Wikiweb System geschrieben, das heißt, Sie können die Artikel jederzeit editieren, wenn Sie einen Fehler gefunden haben, oder etwas hinzufügen wollen.
Editieren Versionen Linkpartnerschaft Bottom Printversion
Keywords: sicher php programmieren sichere php programmierung
Inhaltsverzeichnis
In diesem Tutorial werden Ratschläge zur sicheren PHP-Programmierung gegeben. Tipps um die PHP-Installation des Webservers abzusichern werden hierbei bewusst nicht erwähnt, da es für freie Web-Projekte nicht möglich ist sich auf die sichere Konfiguration des Webservers des jeweiligen Anwenders zu verlassen.
Durch das Anzeigen sämtlicher Fehler- und Hinweismeldungen, ist es möglich, frühzeitig auf Funktionen aufmerksam zu werden, die ihr Verhalten in kommenden Versionen ändern werden. Außerdem werden vorher nicht korrekt initialisierte Variablen angezeigt, wodurch Hacks bei aktiviertem 'register_globals' verhindert werden.
Kopf jeder eigenständigen PHP-Datei:
ini_set('error_reporting', E_ALL | E_STRICT);
Diese Option kann auch direkt in der php.ini oder im Apache für jeden VHost einzeln gesetzt werden.
bei Apache:
php_admin_value error_reporting "E_ALL | E_STRICT"
Jede Benutzereingabe die vom Programm verarbeitet wird, sollte vorher überprüft werden.
Für bestimmte Variableninhaltszustände können verschiedene Arrays angelegt werden. Ich verwende beispielsweise:
Anfang jeder PHP-Datei:
$CLEAN = array(); //Initialisierung der Arrays
$HTML = array();
$MYSQL = array();
$CLEAN['variable'] = $geprüfter_inhalt; //der Inhalt der Variable wurde bereits als sicher Überprüft
$HTML['variable'] = htmlentities($CLEAN['variable']); //für die HTML-Ausgabe bestimmte Variablen
$MYSQL['wert'] = mysql_real_escape_string($wert); //für MySQL maskierter Inhalt
Beispiel Zahlenvariable:
if( !is_int($_POST['zahl']) ) //handelt es sich bei der Variable auch wirklich um eine ganze Zahl?
die(); //versuchte Hacks frühzeitig unterbinden.
Wichtig dabei ist, niemals die bewusst falsche Eingabe des Users korrigieren zu versuchen. Will jemand absichtlich Lücken ausnützen, so sollte das Programm dies effektiv verhindern.
Wäre es hingegen möglich, dass der User versehentlich statt einer Zahl einen Buchstaben eingetragen hat, so kann dafür eine Fehlerbehandlungsroutine geschrieben werden.
Beispiel vorgegebene Strings:
switch( $_POST['wort'] ) {
case 'antwort':
case 'frage':
$CLEAN['wort'] = $_POST['wort'];
break;
case default:
die();
}
Wird per URL die einzubindende Seite übergeben, so empfiehlt sich folgende Variante.
Code:
if( !isset($_GET['page'] )
$page = 'main'; //standardmäßig soll 'main.inc.php' eingebunden werden
else
$page = addslashes(basename($_GET['page'])); //entfernen von Verzeichnisangaben und maskieren der Eingabe
if( file_exists('include/'.$page.'.inc.php') )
require_once('include/'.$page.'.inc.php');
else
die('Fehler! Seite konnte nicht geladen werden.');
Oftmals werden von PHP erstellten Variablen blind vertraut. Doch auch hier sollte immer überlegt werden, welche Werte wirklich vertrauenswürdig sind. Ein Beispiel dafür ist $_FILES['bild']['type'] bei Datei-Uploads. Dieser Wert könnte durch eine manipulierte Datei vergiftet sein. Etwas paranoider ist zwar die Vorsicht bei Rückgabewerten von tmpnam(); doch es kann nie ausgeschlossen werden, dass auch dafür Exploits auftauchen.
Damit Eingaben nicht von PHP vormaskiert werden (was bei einer sicheren Programmierung zu verwirrenden Code oder doppelter Maskierung führen würde), sollte überprüft werden, ob gpc_magic_quotes deaktivert ist.
Code:
if( get_magic_quotes_gpc() )
die('bitte magic_quotes_gpc deaktivieren!');
Hierbei ist es wiederum möglich diese Option in der php.ini bzw. in der Apache-Konfiguration zu setzen. Nicht möglich ist es hingegen dies nachträglich im PHP-Code zu ändern, da dann bereits die Eingaben maskiert wurden.
Folgende Funktionen sind für die Maskierung wichtig:
- mysql_real_escape_string(); für Eingaben, die an MySQL weitergereicht werden
- htmlentities(); für Werte, die in Webseiten eingebunden werden
- escapeshellcmd(); für Werte, die Shell-Kommandos enthalten
- escapeshellarg(); für Werte, die als Shell-Argument verwendet werden
- addslashes(); als Notlösung
Lücken im Session-Management werden häufig von Angreifern ausgenutzt um in Account einzudringen bzw. dessen Rechte auszuweiten.
In den meisten Fällen werden heutzutage Cookies für Sessions verwendet, daher sollte dies auch gleich zur Pflicht für PHP gemacht werden. Ansonsten wäre es für einen Angreifer möglich durch die Übergabe einer Session-ID in der URL fremde Sessions zu ergattern.
Code:
ini_set('session.use_only_cookies', '1');
Passwörter von Benutzern sollten IMMER nur als Hash in der Datenbank gespeichert werden. Aufgrund von Rainbow-Tabellen ist es für Angreifer möglich, solche Hashes in kurzer Zeit zu entschlüsseln. Eine einfache Methode dagegen ist, zu den Passwörtern etwas Salz beizumischen und daraus den Hash-Wert zu bilden.
Code:
$salt = 'geheimer String';
$passwort_hash = md5(md5($CLEAN['passwort'].$salt).$salt);
Wird das Salz geheimgehalten ist es für den Angreifer trotz Kenntnis des Codes nahezu unmöglich, die Hashes zu entschlüsseln. Der zweifache md5()-Aufruf sorgt dabei beim Angreifer für die doppelte Last beim Erstellen von Hash-Tabellen.
Oftmals genügt es, einige wenige Sicherheitsregeln konsequent umzusetzen, um die Anfälligkeit auf Attacken massiv einzudämmen und auch gegen zukünftige Sicherheitslücken seitens PHP gesichert zu sein.
Gibt es noch irgendwelche Fragen, oder wollen Sie über den Artikel diskutieren?
Editieren Versionen Linkpartnerschaft Top Printversion
Haben Sie einen Fehler gefunden? Dann klicken Sie doch auf Editieren, und beheben den Fehler, keine Angst, Sie können nichts zerstören, das Tutorial kann wiederhergestellt werden
Sprachenübersicht/Programmierung/PHP/Security/einfache Schritte zur sicheren PHP-Programmierung