Studieren in Chemnitz. Wissen, was gut ist.





Sicheres Programmieren mit PHP (2)

Überprüfung von Variablenwerten

Vertrauen Sie keinen Werten, die über Browsereingaben, den URL oder Cookies in das PHP-Skript gelangen! Alle externen Parameter, selbst wenn sie aus versteckten Feldern <input type="hidden" ... /> oder Auswahlmenüs kommen, müssen einer Plausibilitätsprüfung unterworfen werden, bevor sie im Programm verwendet werden. Das betrifft alle Werte der Felder _GET, _POST, _COOKIE, sowie _REQUEST. Dazu bietet PHP eine Vielzahl von Möglichkeiten.

   # Wert aus Formular-Eingabefeld "zahl" muss numerisch sein:
   $zahl = (is_numeric($_REQUEST['zahl']) ? $_REQUEST['zahl'] : 0);
Weitere Beispiele finden Sie in: http://www.php-faq.de/q/q-security-variablen.html

Vermeiden Sie beim Zugriff auf Dateien Variablen, insbesondere dann, wenn sie aus Bestandteilen des URLs oder Cookies bestehen. Betrachten Sie das folgende schlechte Beispiel:

  # datei ist Bestandteil des URLs
  include($_REQUEST['datei']); 
Unerwünschte Effekte treten ein, wenn der URL so aussieht: .../script.php?datei=/etc/passwd

Wie kann man es besser machen? Wenn eine Variable nur einen Dateinamen im gleichen Verzeichnis wie das PHP-Skript enthalten darf (aber keinen Pfadnamen), dann reicht häufig die Püfung auf / im Dateinamen:

   if (isset($_REQUEST['datei']) && !ereg('/', $_REQUEST['datei'])) {
       # datei ist gesetzt und enthält kein /
       include($_REQUEST['datei']);
   } else {
       # Fehler ...
   }

Wenn Variablen nur Werte aus einer vorgegebenen Menge annehmen dürfen (z.B. aus einem <select> Menü), sollte dies abgeprüft werden:

   # nur diese drei Werte sind möglich:
   $seiten = array('index.html' => 1, 'kontakt.html' => 1, 
                   'lehre.html' => 1);
   if (isset($_REQUEST['datei']) && isset($seiten[$_REQUEST['datei']])) {
       # datei ist gesetzt und erlaubt
       include($_REQUEST['datei']);
   } else {
       # Fehler ...
   }

Gründlich prüfen sollten Sie unbedingt auch die Parameter für Funktionen zum Starten von externen Programmen, wie system(), exec(), passthru(), popen() und den `Backtick` Operator. Zum Maskieren von Shell-Metazeichen (z.B. Stern oder Semikolon, die mglw. unerwünschte Effekte haben können) eignet sich die Funktion escapeshellarg().

   if (isset($_REQUEST['datei']) && !ereg('/', $_REQUEST['datei'])) {
       # datei ist gesetzt und enthält kein /
       # evtl. Shell-Metazeichen maskieren:
       $datei = escapeshellarg($_REQUEST['datei']);
       system("/bin/ls -l $datei");
   } else {
       # Fehler ...
   }

Weitere Hinweise: http://www.php-faq.de/ch/ch-security.html