Studieren in Chemnitz. Wissen, was gut ist.





Sicheres Programmieren mit PHP (1)

Umgang mit globalen Variablen

Aus historischen Gründen war PHP (bis zum 2.9.2004) auf den zentralen WWW-Servern so eingestellt, dass z.B. Formularwerte oder Cookies gleich als globale Variablen im Skript zur Verfügung stehen. Dies ist zunächst sehr bequem - auf Formulardaten kann man z.B. sehr einfach zugreifen.

Beispiel: Das folgende Skript ist aufrufbar via http://www.tu-chemnitz.de/urz/www/php/ex/1.php

  # Formulareingabe aus <input name="vorname" ... />
  echo "Hallo $vorname \n";      # eingetippter vorname wird ausgegeben

  # Nur wenn die Abfrage vom Rechner 134.109.1.1 kommt, sollen sensible
  # Daten gesendet werden.
  # Umgebungsvariable REMOTE_ADDR enthält IP-Adresse des abfragenden Rechners:

  if ($REMOTE_ADDR == '134.109.1.1') {
      $ok = 1;            # globale Variable $ok
  }
  # ...
  if ($ok == 1) {
      # sende sensible Daten ...
  } else {
      print "Der Zugriff ist nicht erlaubt!";
  }

Dieser "Schutz" ließe sich sehr leicht aushebeln, indem man folgenden URL im Browser angibt: http://www.tu-chemnitz.de/urz/www/php/ex/1.php?ok=1 Der Wert der globalen Variable ok wird aus dem URL übernommen, der Test auf $ok wäre positiv - die sensiblen Daten werden gesendet!

Erste Hilfe: Alle verwendeten Variablen initialisieren - am Anfang: $ok = 0;

Da die Übernahme von Variablen aus "unsicherer Quelle" in den globalen Namensraum von den PHP-Autoren und anderen Experten generell als Sicherheitsrisiko eingestuft wird, wurde dies mit Einführung von Apache 2 abgeschaltet!

Zum Zugriff auf Formulardaten, Cookies usw. bietet PHP neue Felder (sog. Superglobals), die immer verfügbar sind:

Bisher Neu Beschreibung
$name $_GET['name'], $_POST['name'] Zugriff auf Formular-Daten, die per GET oder POST übermittelt wurden
$cname $_COOKIE['cname'] Werte aus Cookies
$name $_REQUEST['name'] Zusammenfassug der 3 o.g. Felder
$VARIABLE $_SERVER['VARIABLE'] Umgebungsvariable des WWW-Servers

Unser unsicheres Beispiel müssen wir ändern:

  # Formulareingabe aus <input name="vorname" ... />
  # Eingetippter vorname wird ausgegeben. Da der Benutzer hier auch HTML
  # eingeben kann, kodieren wir es sicherheitshalber mit htmlspecialchars:
  print "Hallo " . htmlspecialchars($_REQUEST['vorname']) . " \n";;

  $ok = 0;
  # Nur wenn die Abfrage vom Rechner 134.109.1.1 kommt, sollen sensible
  # Daten gesendet werden.
  if ($_SERVER['REMOTE_ADDR'] == '134.109.1.1') {
      $ok = 1;            # globale Variable $ok
  }
  # ...
  if ($ok) {
      # sende sensible Daten ...
  } # ...

$ok ist zwar auch hier eine globale Variable, kann jedoch von Angaben im URL usw. nicht mehr überschrieben werden.