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.