yubb.de-Logo
Tutorials
yubb@yubb
yubbService
Inside yubb

register_globals - Was ist das und welche Folgen haben sie?



Eigentlich ist register_globals nur eine Einstellung. PHP wird größenteils über eine einzige Datei gesteuert. In der steht, welche Funktionen PHP zu leisten hat und wie es sich in bestimmten Situationen zu verhalten hat.
In der Regel ist dies die php.ini, die meist im Windows-Verzeichnis anzufinden ist. Standardmäßig steht in der php.ini, dass register_globals ausgestellt sind.

Gerade PHP-Anfänger haben mit dieser Einschränkung Probleme: Sie haben die "alte Lehre" gelernt, dass man auf Variablen, egal welcher Art, mit $variablenname zugreifen kann (d.h. register_globals stehen auf "On", also aktiviert). Dabei ist es egal, ob die Variable in einem PHP-Script, in der URL oder durch eine Formulareingabe definiert wurde.

Dass diese Verfahrensweise jedoch gefährlich ist, stellt folgendes Beispiel dar: Ein Benutzer hat eine Administration, wo er sich mit Hilfe eines vorher gesetzten Cookies einloggen kann. Das Passwort wird sicherheitshalber in der Adresszeile abgefragt. In der Administration hat er eine Artikelverwaltung, wo er auch Artikel löschen kann. Dies geschieht durch eine Sicherheitsabfrage in einem Formular. Erst dann kann der Admin Artikel löschen.
So weit, so gut. Nur, der Admin hat in seiner PHP-Konfiguration die register_globals auf "On" stehen.

Der ehemals beste Freund vom Admin kommt auf die Seite und weiß selbstverständlich den Nicknamen des Administrators, zufällig auch noch, dass er eine Katze namens "Kitty" hat. Da der Admin diesen Freund vor kurzem beschimpft hat, will der Freund nun die Seite "hacken". Also ruft er mal auf gut Glück "admin.php?name=admin&passwort=kitty" auf. ZACK, ist er in der Administration.
Durch diesen Erfolg angespornt, hegt er die böse Idee: Er will alle Artikel löschen. Deswegen ruft er probehalber mal "artikel_loeschen.php?artikelnr=1&sicher=ja" auf. SCHWUPP, ist der Artikel gelöscht. Er macht fleissig weiter und als der Admin morgens aufwacht, sind alle Artikel weg.

Das wäre mit aktivierten register_globals nicht passiert! Denn mit einer solchen Einstellung unterscheidet PHP zwischen Variablen, die in einem Script definiert wurden, Variablen, die in einer Adresse übergeben wurden, Formulareingaben, Variablen aus einem Cookie und Variablen einer Session.
Dafür stehen folgende fest definierte Variablen zur Verfügung:

$_GET['variablenname'] // liest Variablen aus Adresse
$_POST['variablenname'] // liest Variablen, die aus einer Formularangabe stammen
$_COOKIE['variablenname'] // liest Variablen aus einem Cookie
------
$_ENV['variablenname'] // liest Variablen aus der Umgebung des Benutzers
$_SERVER['variablenname'] // liest Variablen aus dem Server


Somit wäre so ein Hacking-Versuch gescheitert. Denn beim Login mit Hilfe eines Cookie hätte der Admin fest sagen, dass $_COOKIE['name']="admin" und das Passwort, welches aus der dresszeile kommt, $_GET['passwort']="kitty" sein muss, dass der Zugriff auf das Admin-Center gewährt wird.
Fürs Löschen, wo er ein Formular benutzt, hätte er $_POST['artikelnr'] und $_POST['sicher'] abfragen müssen.

Raus aus der Theorie, zeigen wir mal, wie das im Script aussah:
PHP-Datei:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[php]<?
// Falsche Variante

// Login
if($name=="admin" && $passwort=="kitty") {
    
// Zugriff erlaubt
}

// Artikel löschen
if($sicher="ja") {
    
Lösche $artikelnr;
}

------------------------------------------

// Richtige Variante

// Login
if($_COOKIE['name']=="admin" && $_GET['passwort']=="kitty") {
    
// Zugriff erlaubt
}

// Artikel löschen
if($_POST['sicher']=="ja") {
    
Lösche $_POST['artikelnr'];
}
?>





An diesem (zugegebenermaßen einfach gehaltenen) Beispiel kann man erkennen, wie wichtig ausgestellte register_globals sind. Denn nur so kann man eine immense Sicherheitslücke im Programmieren schließen.
Wer Scripte schreibt, sollte immer mit den fest definierten Variablen arbeiten, zugunsten der Sicherheit.

Hat man aber selber ältere Scripte, so muss man aber die Variablen umschreiben, um aus den $_POST[], $_COOKIE[], $_SESSION[] und $_GET[]-Variablen auf die "veraltete" Schreibweise zu trimmen, damit ein älteres Script funktioniert.
Um sich diese Arbeit zu ersparen, kann man folgende zwei Zeilen in das Script einfügen:
PHP-Datei:
1
2
3
4
<?
$GET_POST 
array_merge($_GET$_POST$_COOKIE$_SESSION);
extract($GET_POST);
?>


Damit werden die Variablen "heruntergeregelt" und aus $_POST['bla'] wird $bla, aus $_GET['blubb'] wird $blubb und aus $_COOKIE['lala'] wird $lala.


Geschrieben von Phil Marx am 18.06.2004 (10676x gelesen)
weiterempfehlen weiterempfehlen   Druckversion Druckversion   kommentieren kommentieren

das ist mal wieder ein super Tutorial muss ich sagen, schön lang und ausführlich, aber ich versteh nicht, wieso bei $_POST["bla"] das sicherer ist als $bla....??
Geschrieben von darealplaya
du kannst halt nicht mehr in die URL-Zeile reinhauen ...



angenommen, du willst nur bestimmte Werte übergeben sehen, verwendet man ja SELECT, Radio-Buttons oder Checkboxen. Mit $_POST erwingst du deren Einhaltung, daß es nur über das Formular geht ...



wenn einer index.php?abc=def eingibt, dann geht das nicht
Geschrieben von René
ahh, jetzt ist der "Cent" gefallen-g-
Geschrieben von darealplaya
Bei alten Scripts reicht es auch, wenn man die "gefährlichen" Variablen einfach am Anfang des Scripts löscht und nur diese mit den fest definierten Variablen ersetzt.

z.B. hab ich am anfang einfach unset($auth); gemacht, damit nicht jemand die variable die zur prüfung benutzt wird, ob der user eingeloggt ist, umgangen werden kann.
Geschrieben von darkarrow
Ich würde sagen, dass deine Vorgehensweise noch immer nicht sicher ist.
Lokal auf seinem PC kann sich der Angreifer recht leicht ein Formular basteln, welche sämtliche Variablen per post verschickt und somit die Sicherheitsvorkehrungen umgeht.

<form action="http://beispiel.de/index.php" method="post">
<input type="hidden" name="sicher" value="ja">
<input type="text" name="artikelnummer">
<input type="submit value="löschen"></form>
Geschrieben von Matze