Anzeige
Tutorialbeschreibung

PHP - Teil 09 - Die register_globals-Problematik

PHP - Teil 09 - Die register_globals-Problematik

Mit einem Thema werdet ihr es im Zusammenhang mit PHP immer wieder zu tun bekommen: den Register Globals. Das ist übrigens nicht nur der Fall, wenn ihr PHP-Skripte schreibt. Auch als Anwender stößt man auf die Register-Global-Problematik. So rührten beispielsweise in der Vergangenheit Probleme im Umgang mit dem CMS Joomla! zu einem Großteil von eben jener PHP-Einstellung. Dieses Tutorial zeigt, was es mit den Register Globals eigentlich auf sich hat. Abschließend wird noch ein Blick darauf geworfen, was Entwickler hinsichtlich der Register Globals in PHP6 erwartet.

... übrigens findest du die komplette Serie hier: PHP-Workshop-DVD - Basics & Tricks - Schnapp sie dir in unserem Shop oder in der Kreativ-Flatrate!


In früheren PHP-Versionen ist es sehr einfach gewesen, unsicheren Code zu erstellen. Schuld daran ist eine zunächst einmal sehr angenehme Eigenschaft von PHP. Denn mit Get oder Post übergebene Werte sind im aufgerufenen PHP-Skript automatisch globale Variablen. Somit können bei jedem Programmaufruf mittels URL Variablen übergeben werden. Das ist oftmals gewünscht, kann aber bei unsauber programmiertem Code ein enormes Sicherheitsrisiko sein.

Das folgende Beispiel verdeutlicht diese Problematik. Zunächst wird ein einfaches Formular definiert, in dem ein Eingabefeld enthalten ist. Klickt man die Senden-Schaltfläche an, ruft das die Datei auswertung.php auf. Bei diesem Aufruf wird der auswertung.php per Post-Methode der Inhalt des Eingabefeldes als Variable $vname übergeben.
<form action="auswertung.php" method="post">
 <input type="text" name="vname" />
 <input type="submit" />
</form>

Innerhalb der auswertung.php kann auf die übergebene Variable zugegriffen und deren Wert ausgelesen werden.
<?php
 echo $vname;

?>

 
Das Ergebnis sieht folgendermaßen aus:

Bilder



 
Das ist schön einfach, ist aber eben auch ein Sicherheitsproblem. Denn die Datei auswertung.php könnte von einem Angreifer ebenso auch manuell aufgerufen werden.

http://localhost/auswertung.php?vname=Ich+greife+die+Seite+an
Hier wird der Variablen vname manuell der Wert Ich+greife+die+Seite+an übergeben. Und eben jener übergebene Wert ist es, der innerhalb der auswertung.php ausgelesen wird.

Bilder



 
Anstelle der zuvor übergebenen Zeichenkette könnte ein Angreifer dann natürlich schädlichen Code in die Seite einfügen. Das Problem ist hier also offensichtlich, dass in der auswertung.php keinerlei Mechanismus enthalten ist, der den übergebenen Code überprüft. Und Skripte dieser Art sind wirklich oft anzutreffen.

Im folgenden Beispiel wird überprüft, ob der Wert der Variablen $wert1 gleich ja ist. Ist dies der Fall, wird der Variablen $wichtig der Wert 10 zugewiesen. Dieser Wert wird dann abschließend mittels echo ausgegeben.
<?php
if ($wert1 == 'ja'){
 $wichtig = 10;
}
echo $wichtig;
?>

Der Wert der übergebenen Variablen wird allerdings überhaupt nicht überprüft.

Bilder



 
Und genau dieser Punkt ist es, der viele Skripte so unsicher macht. Besser ist es immer, wenn ihr Variablen explizit auf ihre Herkunft hin überprüft. An diesem Punkt kommen die Register Globals ins Spiel. Und mit diesen Register Globals werdet ihr es – ob ihr nun PHP-Skripte selbst entwickelt oder PHP-basierte Anwendungen einsetzt – immer wieder zu tun bekommen. Denn leider sind die Register Globals aus Sicherheitsaspekten heraus mindestens zweifelhaft. Die Einstellung bewirkt nämlich, dass PHP für jede übergebene Variable eine globale Variable erzeugt.

Ob die Register Globals bei euch aktiviert sind, könnt ihr ganz einfach überprüfen. Legt dazu eine PHP-Datei an, in der die Funktion phpinfo() enthalten ist.
<?php
 phpinfo();
?>

Wenn ihr diese Datei im Browser aufruft, werden alle wichtigen Informationen zur aktuellen PHP-Konfiguration angezeigt. Unter anderem sind dort auch die Einstellungen zu den Register Globals zu finden.

Bilder



 
Steht dort register_globals = on, sind die Register Globals aktiv. Bei aktivierten Register Globals lassen sich die Variablen dann folgendermaßen verwenden:
&$_SERVER['REMOTE_ADDR']

Hier wird innerhalb der Servervariablen die IP-Adresse des Besuchers gespeichert. Bei aktivierten Register Globals kann auf diese Variable folgendermaßen zugegriffen werden:
$REMOTE_ADDR

Das ist zwar praktisch, sollte so aber in Web-Anwendungen unbedingt vermieden werden.

Ändern lässt sich die Konfiguration innerhalb der php.ini. Sucht dort nach dem Eintrag register_globals.
register_globals = On

Wenn dieser Wert auf On steht, setzt ihr ihn auf Off.

register_globals = Off
Damit die Änderungen an der Konfiguration übernommen werden, müsst ihr den Server neu starten.

Was bewirkt es nun eigentlich, wenn ihr register_globals = Off einstellt? Das lässt sich am besten anhand eines Beispiels zeigen. Zunächst die Variante, bei der mit register_globals = on gearbeitet wird.
if ($pwd == "123456") {
 $is_logged_in = true;
}
if ($is_logged_in) {
 echo("Streng geheim.");
}

Skripte in dieser Art sind sehr oft anzutreffen. Denn auf deren Basis lassen sich Webseitenbereiche definieren, auf die ausschließlich solche Benutzer zugreifen dürfen, die sich registriert und sich dann auch tatsächlich eingeloggt haben. Das Problem am aktuellen Beispiel ist nun jedoch, dass die Herkunft der Variablen $pwd nicht überprüft werden kann. So muss die Variable hier eben nicht aus einem Cookie stammen, sondern kann auch manuell mittels Get-Methode übergeben werden. So ist dieses Skript zwar auf den ersten Blick leicht zu programmieren, es sollte so aber niemals in der Praxis eingesetzt werden. Denn jeder, der sich etwas mit PHP auskennt, weiß natürlich um die Schwächen solcher Anwendungen. Und noch ein Problem tritt bei diesem Skript auf: Setzt man es auf einem Server ein, bei dem der Wert von register_globals auf Off gesetzt ist, funktioniert es nicht. Genau das ist übrigens auch der Grund für viele Fehler, die in früheren Versionen von Joomla! im Zusammenhang mit den Register Globals aufgetreten sind. (Andere Anwendungen sind von dieser Problematik übrigens auch betroffen. Joomla! bildet hier also keine Ausnahme).

Verhindern lassen sich die Sicherheitsprobleme, indem man die superglobalen Arrays verwendet, die im Rahmen dieser PHP-Reihe bereits vorgestellt wurden. Das folgende Beispiel zeigt noch einmal dieselbe Anwendung, dieses Mal allerdings unter Zuhilfenahme der superglobalen Arrays.
$is_logged_in = false;

if ($_COOKIE['pwd'] == "123456") {

 $is_logged_in = true;

}

if ($is_logged_in) {

 echo("Streng geheim.");

}

Hier kann der durch das Skript geschützte Bereich tatsächlich nur betreten werden, wenn es die angegebene Cookie-Variable auch tatsächlich gibt. Eine Manipulation der Variable über Get ist hier nicht möglich.


Die Register Globals in PHP6

In PHP6 ist der register_globals-Schalter nicht mehr enthalten. Gleiches gilt dort auch für die globalen Variablen $HTTP_POST_VARS, $HTTP_GET_VARS und $HTTP_COOKIE_VARS. In diesem Zusammenhang wird es in PHP6 auch den Parameter register_long_arrays nicht mehr geben. Ab PHP6 existieren in diesem Kontext dann nur noch die beiden Variablen $_GET und $_POST. Das wird in einigen Anwendungen zwangsläufig zu Problemen führen. Wenn euer Provider auf PHP6 umstellt, bevor ihr die Skripte angepasst habt, könnt ihr euch des folgenden Codes bedienen:
if (!ini_get('register_long_arrays')){

  $HTTP_POST_VARS =& $_POST;
  $HTTP_GET_VARS =& $_GET;
  $HTTP_COOKIE_VARS =& $_COOKIE;
  $HTTP_SERVER_VARS =& $_SERVER;
  $HTTP_ENV_VARS =& $_ENV;
  $HTTP_POST_FILES =& $_FILES;
}

Auf diese Weise lässt sich die register_globals-Problematik in PHP6 umgehen.

Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von hicom
  • 24.08.2011 - 13:56

Danke für das Tutorial. Etwas kurz aber der Tip zum Schluss mit den Referenzen war ganz nett.

Portrait von AmbIT
  • 02.05.2011 - 03:00

Also mir persönlich ist das zu knapp erklärt. Es ist zwar alles wesentliche enthalten aber die Beispiele sind sehr knapp und die Erläuterung wirkt auf mich sehr sprunghaft. Ich hatte schon in die ersten Tuts von Daniel reingelesen und fand sie etwas knapp, leider hat sich das bis Nr. 9 nicht geändert. Aber die Idee ist nice denn genau diese Art von Hintergrundinfos vermisse ich in vielen Büchern.

Gruß Maik

Portrait von MegaAdi
  • 27.04.2011 - 12:13

Super erklärt und sehr informativ!
Danke für die schöne Ausführung über Sicherheitsrisiken mit register_global.


Adrian

x
×
×