Datenbankprogrammierung - PHP - Tipps & Tricks
Sichere Seiten mit PHP 5 - Teil I
Einige der grundlegendsten Sicherheitsvorkehrungen können Sie bereits treffen, bevor Sie auch nur eine Zeile Quelltext geschrieben haben. Sämtliche Einstellungen, die das Verhalten von PHP betreffen, befinden sich in einer einzigen Konfigurations-Datei, der php.ini . Auch zum Thema Sicherheit findet sich dort eine ganze Reihe an Parametern, von denen einige wichtig, einige unwichtig und wieder einige zwar wichtig, aber nicht wirklich im Alltag realistisch zu gebrauchen sind.
In diesem Tutorial sollen daher auch nur einige zentrale Einstellungen gezeigt werden, die schnell zu konfigurieren sind, aber bereits einige kritische Probleme verhindern können, ohne Sie dabei jedoch in Ihrer eigentlichen Programmierarbeit wesentlich zu behindern.
Sie können die php.ini mit einem beliebigen Editor öffnen und bearbeiten, da es sich um eine ganz einfache Text-Datei handelt. Lassen Sie dann den Editor einfach nach den hier aufgeführten Schlüsselwörtern (also z.B. „register_globals") suchen.
php.ini finden
Gerade auf Servern, auf denen schon seit langer Zeit immer mal wieder neue PHP-Versionen installiert wurden, kann es passieren, dass Sie schlichtweg verzweifeln, weil eine geänderte Einstellung in der php.ini-Datei offenbar zu keinerlei Änderungen im Verhalten von PHP führt. Schließlich müssen Sie feststellen, dass Sie die ganze Zeit die völlig falsche Datei bearbeiten und PHP eine gänzliche andere Konfigurations-Datei aktuell nutzt. (Es ist nämlich keinesfalls so, dass die php.ini immer zwangsläufig im gleichen Ordner zu finden ist.)
Abhilfe schafft hier die Funktion phpinfo(), die Ihnen sämtliche Einstellungen Ihrer momentan aktiven PHP-Installation anzeigt. Schreiben Sie sich einfach ein kleines Skript phpinfo.php und kopieren Sie es an eine beliebige Stelle in Ihrem Webverzeichnis.
Wenn Sie diese Datei aufrufen, erhalten Sie eine lange Liste aller gesetzten Parameter, unter anderem auch den Ort der genutzten php.ini-Datei.
Ausgabe von phpinfo()
In der Zeile „Loaded Configuration File" finden Sie den Pfad zu der geladenen php.ini-Datei und nur diese sollten Sie auch tatsächlich ändern.
Vergessen Sie bitte auf keinen Fall, dieses Skript spätestens dann wieder zu löschen, wenn Ihre Webanwendung online geht! Die Informationen, die phpinfo() liefert, sollten niemals in die falschen Hände geraten!
register_globals = off
Vor der PHP-Version 4.2 war dieser Wert standardmäßig auf ON, also aktiviert. Man wollte es dem Programmierer wohl so einfach wie nur möglich machen. register_globals=on bedeutet vor allem, dass sämtliche Parameter, die an ein Skript über ein Formular oder einen Query-String in der Adress-Zeile übergeben werden (also per GET oder POST), sofort als Variablen zur Verfügung stehen.
Betrachten wir einmal folgenden Auszug aus einem kleinen Formular in einer Datei formular.php:
...
<?
echo "Sie haben eingegeben: ".$nutzername;
?>
...
<form name="form1"" action="formular.php" method="post">
<input type="text" name="nutzername" value="" />
<input type="submit" name="speichern" value="Speichern" />
</form>
...
Ganzen Artikel lesen...
Es gibt ein Textfeld mit dem Namen „nutzername" und einen Submit-Button. Mehr nicht. Ruft man dieses Skript nun mit register_globals=on auf, gibt einen Wert in die Textbox ein und schickt das Formular ab, so steht die Variable $nutzername sofort im Skript zur Verfügung. Die Zeile echo $nutzername würde also eine Ausgabe erzeugen.
Das gleiche Ergebnis erhalten Sie aber auch, wenn Sie das Skript so aufrufen:
formular.php?nutzername=Tralala
Der Parameter, die hier in der URL übergeben wird, wird ebenfalls sofort als Variable innerhalb von PHP übernommen. Man kann sich vorstellen, welche Möglichkeiten es bietet, so von außen Einfluss auf ein Skript zu nehmen, insbesondere auch, weil man ohne weiteres Variablen übergeben kann, die eigentlich gar nicht aus einem Formular kommen:
Gibt es in der Programmierung eine Variable admin und wird diese Variable nicht explizit gesetzt, so würde der Wert aus der URL in die Programmierung übernommen und aus einem einfachen Nutzer wäre pötzlich ein Administrator mit entsprechenden Rechten geworden.
Daher wurde register_globals nach Version 4.2 standardmäßig auf off gesetzt, also deaktiviert. Das ist auch durchaus vernünftig, und Sie sollten sich erst gar nicht angewöhnen, auf die alte Art und Weise zu arbeiten.
Lassen Sie also register_globals ausgeschaltet und nutzen Sie immer (wie auch überall in diesem Buch) die globalen Arrays $_REQUEST, $_POST, $_GET, $_COOKIES und $_SESSION, um Ihre Variablen aus den verschiedenen Quellen zu übernehmen. Das Skript oben sollte also so aussehen:
...
<?
echo "Sie haben eingegeben: ".$_POST['nutzername'];
?>
...
<form name="form1"" action="formular.php" method="post">
<input type="text" name="nutzername" value="" />
<input type="submit" name="speichern" value="Speichern" />
</form>
...
Sicher könnte man argumentieren, dass die Chance eines solchen Angriffs eher gering ist und meist auch nur in Sonderfällen eine echte Gefahr darstellt. (Immerhin müsste im obigen Beispiel der Angreifer wissen, dass es eine Variable $admin überhaupt gibt.) Außerdem macht der Umweg über die oben genannten globalen Arrays das Programmieren nicht deutlich komplizierter? Widerspricht das nicht unseremGrundgedanken und sollten Sie daher- um noch schneller arbeiten zu können - nicht doch einfach lieber auf diese Sicherheitseinstellung verzichten?
Nein, sollten Sie nicht.
Zunächst ist der Gebrauch von $_REQUEST & Co nicht kompliziert. Wenn Sie wie in den vorherigen Kapiteln gezeigt, die Möglichkeit nutzen, Formelemente in einer Seite als Array anzulegen (also Element-Namen vergeben wie „data[nutzername]"), dann reduziert sich das Problem meist auf eine einzige zusätzliche Zeile:
...
<?
// Hole Werte aus globalem Array
$data = $_POST['data'];
// Jetzt kann damit gearbeitet werden
echo $data['entry_title'];
echo $data['entry_content'];
...
?>
...
<label >Titel:</label>
<input type="text" name="data[entry_title]" id="data[entry_title]" value="" /><br /><br />
<label >Inhalt:</label>
<textarea name="data[entry_content]" id="data[entry_content]"><textarea><br /><br />
...
Hinzu kommt, dass register_globals=off inzwischen absoluter Standard geworden ist. Wenn Sie mit den globalen Arrays arbeiten, dann wird Ihre Programmierung auf jedem Server funktionieren - ganz egal, wie register_globals eingestellt ist. Entwickeln Sie jedoch mit register_globals=on, also mit der alten, direkten Variablen-Übergabe, so wird Ihr Skript auf vielen Servern später schlichtweg nicht laufen und dann werden Sie richtig Zeit verlieren, wenn Sie sämtliche Skripte umschreiben müssen.
Die passende Ergänzung zu diesem Artikel:
 | PHP5 / MySQL5 Produktart: Buch ISBN 978-3-645-60010-1 Versandkostenfrei* direkt beim Verlag bestellen
30,00 € 
|

Marcus Straßer
Lernen Sie die ganze Vielfalt vom Franzis Buch- und Softwareverlag kennen