Ergebnis 1 bis 10 von 10

Thema: PHP: Die register_globals-Problematik

  1. #1

    PHP: Die register_globals-Problematik

    Die register_globals = On Problematik

    Was bewirkt register_globals = On?

    Ist die Anweisung register_globals auf On (An) geschaltet, sind alle Variablen unter ihrem Namen verfügbar. Ein Beispiel:

    http://www.beispiel.de/index.php?variable1=hallo

    Hier werden über die URI (GET Methode) der Variable variable1 der Wert hallo gegeben. Diese Variable kann ein PHP Skript mit $variable1 aufrufen.
    Das ist auch mit der POST Methode möglich, dazu benötigt ein <input /> Element einen individuellen Namen:

    Code:
    ...
    <form action="./auswertung.php" method="post">
    <input type="text" name="variable1" />
    </form>
    ...
    Wird das Formular abgesendet kann ein PHP Skript die Variable $variable1 bearbeiten.

    Wo liegt das Problem?

    Da alle Variablen unter ihrem gegebenen Namen verfügbar sind, können sich Variablen aus der POST und der GET Methode mit selben Namen überschreiben, ferner kann PHP nicht unterscheiden, ob die Variable ihren Wert über die POST oder die GET Methode erhielt.
    Warum ist das wichtig? Nehmen wir an, der Benutzer einer Seite kann über ein Auswahlfeld eine Datei auswählen, von der der Quelltext gezeigt werden soll. Das Formular bietet nur Dateien an, die jeder sehen darf, da PHP aber nicht zwischen POST und GET Daten unterscheiden kann könnte ein Benutzer folgende URI eingeben:

    http://www.beispiel.de/formular-ziel...dmin_login.php

    Das Skript, das den Quelltext ausgibt, gibt nun den Quelltext der Datei admin_login.php aus. Eine hier vorhandene Passwortabfrage könnte so aussehen:

    Code:
    if ( $passwort == 'geheim' )
    { echo 'alle geheimen administrativen Funktionen'; }
    else
    { echo 'leider kein Recht auf Zugriff'; }
    Ein Hacker wüsste jetzt das Passwort für den Administrativen Bereich dieser Webseite.
    Dieses Beispiel entsprang der Fantasie des Autors, kann aber jederzeit schmerzhafte Tatsache werden, da es zeigt, welche Gefahr von register_globals = On ausgehen kann.
    Bei einem Skript wie diesem bieten sich noch andere Sicherheitslöcher an, aber diese stehen nicht direkt mit register_globals im Zusammenhang.

    Was wird dagegen unternommen?

    In der PHP Version 4.1 wurden so genannte Super- oder Autoglobale Arrays eingeführt, diese enthalten POST und GET, aber auch COOKIE, SESSION, FILES, SERVER und ENVIROMENT Daten. So werden diese Variablen im PHP Skript aufgerufen:

    $_POST['variable1']
    $_GET['variable1']

    Ein unübersehbarer Vorteil: PHP unterscheidet, ob die Variable ihren Wert über die POST oder die GET Methode erhielt, ferner überschriben sich POST und GET Variablen nicht, die den selben Namen haben. Lautet der Code des PHP Skripts, das den Quelltext ausgibt also wie folgt, wird eine Dateiauswahl per URI unmöglich gemacht.

    <?php show_source ( $_POST['datei'] ); ?>

    Achtung: Diese Methode macht es einem Hacker nur etwas schwerer. Da dieser jetzt selbst ein Formular schreiben könnte, ist es wichtig, die Variable $_POST['datei'] auf verschiedene Eigenschaften zu prüfen.

    Welche Superglobalen Arrays gibt es?

    [b]Variable - Verwendung[b]
    $_POST[''] für POST Daten
    $_GET[''] für GET Daten
    $_COOKIE[''] für Daten, die ein Cookie übermittelt
    $_REQUEST enthält POST, GET und COOKIE Daten (vermeiden, wenn nicht unbedingt benötigt)
    $_SERVER[''] für Daten, die vom Server ausgehen und an diesen gesendet werden, z.B. eigene IP Adresse (per phpinfo() einsehbar)
    $_ENV[''] für Umgebungsvariablen (per phpinfo() einsehbar)
    $_SESSION[''] für Daten, die in einer Session gespeichert werden (statt session_register($variable) sollte $_SESSION['variable'] = 'wert'; verwendet werden)
    $_FILES[''] für Dateien, die über ein Formular hochgeladen werden

    Das $_FILES Array enthält ein weiteres Array:

    Inhalt eines Formulars:
    Code:
    ...
    <input type="file" name="name_des_feldes"/>
    ...
    Diese Daten sind aufrufbar:
    Variable (Inhalt)
    $_FILES['name_des_feldes']['name'] (Name der Datei)
    $_FILES['name_des_feldes']['type'] (MIME Typ der Datei)
    $_FILES['name_des_feldes']['tmp_name'] (Name der Temporär angelegten Datei)
    $_FILES['name_des_feldes']['error'] (Fehlercode, erst seit PHP Version 4.2)
    $_FILES['name_des_feldes']['size'] (Dateigröße in Byte)

    Das ermöglicht ein einfaches realisieren eines gleichzeitigen Uploads mehrerer Dateien.

    Noch etwas?

    $_* Variablen sind global verfügbar, d.h. sie können in eigenen Funktionen ohne die Angabe "global \$variable;" aufgerufen werden.

    Geändert von mitaki (24.06.2011 um 21:40 Uhr)

  2. #2
    Sehr gut Mitaki
    Da sehen einige das register_globals lieber auf "off" stehen sollte .
    Man sieht ja eh noch das einige das auf "on" haben und somit opfer der angreifer werden. :/
    Naja mach weiter so Mitaki

  3. #3
    Hach, ich liebe es, wie du uns dein Wissen häppchenweise präsentierst. <3
    Schmackhaft, sehr gelungen, mein Freund.

  4. #4
    mal daran gedacht, dein geld damit zu verdienen, dau sichere bücher übers web zu schreiben? Das war sehr schön anschaulich erklärt, hab schon schlechteres in vielen komerziellen Büchern gelesen.

    Oder mach zumindest sowas wie Selfhtml, (das ja wohl eh vor dem aus steht?) über die Problematik von Barierefreiem Deisgn, sicherheit usw.

  5. #5
    Zitat Zitat
    mal daran gedacht, dein geld damit zu verdienen, dau sichere bücher übers web zu schreiben? Das war sehr schön anschaulich erklärt, hab schon schlechteres in vielen komerziellen Büchern gelesen.

    Oder mach zumindest sowas wie Selfhtml, (das ja wohl eh vor dem aus steht?) über die Problematik von Barierefreiem Deisgn, sicherheit usw.
    Dem Schließe ich mich mal an! Wuerde es sogar kaufen.

  6. #6
    Zitat Zitat von mitaki Beitrag anzeigen
    Bei der Verwendung der Variablen, die register_globals erzeugt ist keine Unterscheidung möglich, woher diese Daten kommen. Im gezeigten Beispiel würde PHP nur die Variable variable1 kennen. Ob deren Inhalt aus der URI kommt oder aus dem Formular kann PHP nicht unterscheiden. Welcher Wert tatsächlich verwendet wurde weiß PHP nicht. Da die Konfiguration, welche Herkunft Priorität besitzt frei verändert werden kann ist eine allgemein gültige Aussage nicht möglich.
    Dazu sei gesagt, dass man die Einstellung in der php.ini per variables_order bzw. per gpc_order ändern kann.

    Sehr gelungene Beschreibung des Problems, Taki.

  7. #7
    register_globals hat noch eine weitere Gefahrenquelle: Bei PHP ist es nicht üblich, Variablen explizit zu initialisieren. Wenn man jetzt also irgendwo $foobar verwendet und ein User den URI durch &foobar=bla ergänzt, dann hat $foobar im Skript bei der "Initialisierung" den Wert bla. So sind u.U. Angriffe möglich.

    Mit folgendem Snippet (als allererstes auszuführen) kann man das abstellen. Effektiv simuliert es register_globals = off.
    PHP-Code:
    foreach($_REQUEST as $key => $value)
    {
      unset($
    $key);

    Es ich nicht nötig, zu überprüfen, ob die Variablen auch existieren; PHP hat kein Problem damit, nichtexistente Variablen zu nullen.

  8. #8
    Zitat Zitat von Jesus_666 Beitrag anzeigen
    register_globals hat noch eine weitere Gefahrenquelle: Bei PHP ist es nicht üblich, Variablen explizit zu initialisieren. Wenn man jetzt also irgendwo $foobar verwendet und ein User den URI durch &foobar=bla ergänzt, dann hat $foobar im Skript bei der "Initialisierung" den Wert bla. So sind u.U. Angriffe möglich.

    Mit folgendem Snippet (als allererstes auszuführen) kann man das abstellen. Effektiv simuliert es register_globals = off.
    PHP-Code:
    foreach($_REQUEST as $key => $value)
    {
      unset($
    $key);

    Es ich nicht nötig, zu überprüfen, ob die Variablen auch existieren; PHP hat kein Problem damit, nichtexistente Variablen zu nullen.
    Das ist dann aber lustig bei ?_GET=xd&_POST=fu - Schon sind die beiden Arrays leer

  9. #9
    Zitat Zitat
    mal daran gedacht, dein geld damit zu verdienen, dau sichere bücher übers web zu schreiben? Das war sehr schön anschaulich erklärt, hab schon schlechteres in vielen komerziellen Büchern gelesen.
    Naja, es gibt Dinge, die ich kann und Dinge, die ich nicht kann. Das Bücherschreiben gehört zu letzterem ^^ So lange ich einen Beruf ausübe und hier nicht verbannt werde spricht auch nichts dagegen weiterzumachen (sofern mir nicht die Ideen ausgehen).

    Zitat Zitat
    Oder mach zumindest sowas wie Selfhtml, (das ja wohl eh vor dem aus steht?)
    Jain. Es wird wohl kein SELFHTML 9 geben. Die Version 8.1 wird aber noch gepflegt. Bald erscheint 8.1.2, in welchem nicht nur von mir gemeldete Fehler korrigiert werden, sondern auch deutlich wird, dass SELFHTML im aktuellen Zustand einfach veraltet ist.

    Zitat Zitat
    Dazu sei gesagt, dass man die Einstellung in der php.ini per variables_order bzw. per gpc_order ändern kann.
    Wobei ich das jetzt ausgelassen habe, da das der Benutzer in der Regel nicht ändern kann. Zu register_globals = Off wird er ja gezwungen und sollte daher Bescheid wissen. Dann sind die von dir genannten Einstellungen auch nicht mehr so wichtig.

    Zitat Zitat
    Bei PHP ist es nicht üblich, Variablen explizit zu initialisieren.
    Danke, daran hatte ich nicht gedacht. Werde bei einer späteren Aktualisierung sehen, wie ich das mit einbauen kann.

    Zitat Zitat
    Das ist dann aber lustig bei ?_GET=xd&_POST=fu - Schon sind die beiden Arrays leer
    Nein, _REQUEST enthält ja nicht _GET und _POST sondern ist eine Zusammenfassung aus dem Inhalt von _GET, _POST und _COOKIE. Hier werden dann ähnlich rg=On die Variablen überschrieben, die den selben Namen teilen.

  10. #10
    Zitat Zitat von mitaki Beitrag anzeigen
    Nein, _REQUEST enthält ja nicht _GET und _POST sondern ist eine Zusammenfassung aus dem Inhalt von _GET, _POST und _COOKIE. Hier werden dann ähnlich rg=On die Variablen überschrieben, die den selben Namen teilen.
    Nein, es stimmt tatsächlich. Wenn $_REQUEST einen Schlüssel namens _GET hat und ich $$eintrag unsette wird $_GET genullt.

    Hier ist eine sicherere Version:
    PHP-Code:
    if ('' != ini_get('register_globals'))
    {
      foreach(
    $_REQUEST as $key => $value)
      {
        
    $lkey strtolower($key);
        if (
    $lkey != 'globals' && $lkey != '_get' && $lkey != '_post' &&
            
    $lkey != '_cookie' && $lkey != '_files' && $lkey != '_request')
        {
          unset($
    $key);
        }
      }


Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •