Klaus: PHP: register_globals per Script verhindern

Hallo,
wie ihr ja alle wisst, ist register_globals = On oft ein doch großes Sicherheitsproblem.
Zwar ist dann die Software fehlerhaft, aber man kann ja nie ganz ausschließen, dass ein Programmierer alle Variablen vorher initialisiert hat.

Darum habe ich gerade in 'Besser PHP Programmieren' folgenden Script gefunden:

  
<?php  
function unregister_globals() {  
   //Variablen speichern  
   $REQUEST = $_REQUEST;  
   $GET = $_GET;  
   $POST = $_POST;  
   $COOKIE = $_COOKIE;  
   $FILES = $_FILES;  
   $ENV = $_ENV;  
   $SERVER = $_SERVER;  
   if(isset($_SESSION))  
      $SESSION = $_SESSION;  
  
   foreach($GLOBALS as $feld=>$wert) {  
      if($feld != "GLOBALS")  
         unset($GLOBALS[$feld]);  
   }  
  
   //Variablen zurückschreiben  
   $_REQUEST = $REQUEST;  
   $_GET = $GET;  
   $_POST = $POST;  
   $_COOKIE = $COOKIE;  
   $_FILES = $FILES;  
   $_ENV = $ENV;  
   $_SERVER = $SERVER;  
   if(isset($SESSION))  
      $_SESSION = $SESSION;  
}  
  
//Nur aufrufen wenn es auf ON steht  
if(ini_get('register_globals'))  
   unregister_globals();  
  
$username = $_GET['username'];  
  
if($username == "klaus") {  
   $log=1;  
}  
  
if($log == 1){  
   echo "Geheimer Bereich";  
}  
  
?>

Ohne die Funktion wäre es jetzt hier möglich in den Geheimen Bereich zu gelangen, auch wenn man den Username gar nicht kennt.
Einfach ?log=1 anhängen und schon ist man drinne.

Die Funktion löscht aber am Anfang alle Variablen, bis auf die superglobalen, so das ein Angreifer keinen x beliebigen, nicht initialisierten Variablen, verändern kann.

Ich wollte mal fragen was ihr davon haltet, wenn ein umfangreicher Script diese Funktion standardmäßig auf jeder Seite vorhher aufruft.
So könnte man ja Programmierfehler wie im Bsp-Script vorbeugen und abdämpfen.
Oder haltet ihr dies für eine schlechte Idee?
Klar dieser Script sollte keine schlechte Programmierung ausgleichen, sondern noch als extra Zusatzschutz für die Release-Version.

Wie seht ihr das?

Grüße
Klaus

  1. Hi,

    Wie seht ihr das?

    So, als wenn Das Finazamt Dir einen Brief schickt: "Mitteilung über Pfändung..." und Du der meinung bist, du könntest das nun mittels nachgereichter Steuererklärung noch wieder beseitigen.

    LG

    Chris

    1. Hallo,

      Wie seht ihr das?

      So, als wenn Das Finazamt Dir einen Brief schickt: "Mitteilung über Pfändung..." und Du der meinung bist, du könntest das nun mittels nachgereichter Steuererklärung noch wieder beseitigen.

      Wie ich sagte, dies soll kein Wundermittel gegen Programmierfehler sein.
      Aber wenn ein Script an die 100 000 Zeilen Code hat, ist es sehr sehr mühselig, jede Variable zu überprüfen, vorallem bei häufigeren Änderungen.

      Oft sieht man z.B.
      if($email_show == true)
        $email = "info@google.com";

      //...
      echo "Email: $email <br>";

      Sofern aver $email_show == false ist, könnte man ja per URL $email manipulieren.
      Dort wäre also eine Schwäche von z.B. XSS.

      Mit dem Script wird ja nur sichergestellt, dass der Script immer so läuft, also wäre register_globals = Off.

      P.S. Die Ausführungszeit der Funktion ist auch trivial niedrig.

      Grüße
      Klaus

      1. Hallo Klaus.

        Aber wenn ein Script an die 100 000 Zeilen Code hat, ist es sehr sehr mühselig, jede Variable zu überprüfen, vorallem bei häufigeren Änderungen.

        Nicht im Geringsten. Jeder moderne Editor hat eine Suchen und Ersetzen-Funktion.
        Damit lassen sich die sich auf register_globals=on stützenden Variablen schnell korrigieren.

        Einen schönen Sonntag noch.

        Gruß, Ashura

        --
        Selfcode: sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:) fl:( ss:) ls:[ js:|
        30 Days to becoming an Opera8 Lover -- Opera Mini on Treo
        Meine Browser: Opera 8.02 | Firefox 1.0.6 | Lynx 2.8.5 | Netscape 4.7 | IE 6.0
        [Deshalb frei! - Argumente pro freie Software]
        1. Hallo Ashura,

          Nicht im Geringsten. Jeder moderne Editor hat eine Suchen und Ersetzen-Funktion.
          Damit lassen sich die sich auf register_globals=on stützenden Variablen schnell korrigieren.

          Das musst Du mir aber erst einmal vormachen.
          Insbesondere interessant, wenn auch noch session_register() im Einsatz ist und man die Quellen nun entflechten möchte.

          Vielfach sind die Variablen auch nicht initialisiert ud das Scipt funktioniert nur deshalb...

          LG

          Chris

          1. Hallo Chris.

            Nicht im Geringsten. Jeder moderne Editor hat eine Suchen und Ersetzen-Funktion.
            Damit lassen sich die sich auf register_globals=on stützenden Variablen schnell korrigieren.

            Das musst Du mir aber erst einmal vormachen.

            Muss ich nicht.

            Insbesondere interessant, wenn auch noch session_register() im Einsatz ist und man die Quellen nun entflechten möchte.

            Wenn man dies getan hat, kann man die Variablen ihrem Ursprung (GET, POST, ...) zuordnen.

            Vielfach sind die Variablen auch nicht initialisiert ud das Scipt funktioniert nur deshalb...

            Merkwürdiges Skript, wenn du mich fragst.

            Einen schönen Sonntag noch.

            Gruß, Ashura

            --
            Selfcode: sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:) fl:( ss:) ls:[ js:|
            30 Days to becoming an Opera8 Lover -- Opera Mini on Treo
            Meine Browser: Opera 8.02 | Firefox 1.0.6 | Lynx 2.8.5 | Netscape 4.7 | IE 6.0
            [Deshalb frei! - Argumente pro freie Software]
            1. Hi Ashura,

              Merkwürdiges Skript, wenn du mich fragst.

              Wann muss ich den die Variable initialisiern?
              Vor oder nach dem session_register()

              Ist das bei jeder PHP-Verison gleich?

              LG

              Chris

      2. Wie seht ihr das?

        So, als wenn Das Finazamt Dir einen Brief schickt: "Mitteilung über Pfändung..." und Du der meinung bist, du könntest das nun mittels nachgereichter Steuererklärung noch wieder beseitigen.
        Wie ich sagte, dies soll kein Wundermittel gegen Programmierfehler sein.
        Aber wenn ein Script an die 100 000 Zeilen Code hat, ist es sehr sehr mühselig, jede Variable zu überprüfen, vorallem bei häufigeren Änderungen.

        Vielleicht funktioniert ein anderes Beispiel: Dein Wasserhahn ist undicht und anstatt eine neue Dichtung einzubauen bindest du einen Lappen um den Auslass, damit's nicht so laut tropft.

  2. echo $begrüßung;

    So könnte man ja Programmierfehler wie im Bsp-Script vorbeugen und abdämpfen.
    Oder haltet ihr dies für eine schlechte Idee?

    Ja.
    Wesentlich besser ist es, beim Entwickeln das error_reporting auf E_ALL zu setzen und sich damit Notices über nicht initialisierte Variablen ausgeben zu lassen.
    Und vor allem sich gleich angewöhnen, Variablen immer mit einem definierten Wert zu initialisieren und Werte von außen (EGPCS-Variablen) auf Existenz und erwarteten Inhalt zu prüfen.

    echo "$verabschiedung $name";

  3. if(ini_get('register_globals'))
       unregister_globals();

    Ich wäre ja eher für

    if (ini_get('register_globals')) {
        error_log("Wer register_globals einsetzt, ist doof!");
        die();
    }

    1. Hi Sonntagsfahrer,

      Ich wäre ja eher für

      if (ini_get('register_globals')) {
          error_log("Wer register_globals einsetzt, ist doof!");
          die();
      }

      Du scheinst zu vergessen, dass nicht alle Leute auf ihren Produktivserver die Möglichkeit besitzen, register_globals zu deaktivieren.

      MfG, Dennis.

      --
      Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
      Man kann die Menschen zur Vernunft bringen, indem man sie dazu verleitet, daß sie selbst denken. (Voltaire)
      1. Hi Dennis,

        Du scheinst zu vergessen, dass nicht alle Leute auf ihren Produktivserver die Möglichkeit besitzen, register_globals zu deaktivieren.

        Woraus schließt Du das?
        Er hat doch nur gesagt, 'Wer register_globals einsetzt, ist doof'.

        Wenn der Provider das obligatorisch macht, kann derjenige doch den Provider wechseln.

        LG
        Chris

  4. Hi,

    Einfach ?log=1 anhängen und schon ist man drinne.

    Einfach

    if ($passwort == "abc) {
      $log = true;
      // sonst was...
    } else {
      $log = false;
      // sonst was...
    }

    Kostet dich nur ein else im Logonscript mehr...

    Ich wollte mal fragen was ihr davon haltet, wenn ein umfangreicher Script diese Funktion standardmäßig auf jeder Seite vorhher aufruft.

    Wenn die Seite gut besucht ist, kriegst du evtl. Performanceprobleme.

    Oder haltet ihr dies für eine schlechte Idee?

    Ja.

    Versuchs mal über die .htaccess:

    php_flag register_globals [on|off]

    E7

    1. Hi e7,

      Einfach

      if ($passwort == "abc) {
        $log = true;
        // sonst was...
      } else {
        $log = false;
        // sonst was...
      }

      Kostet dich nur ein else im Logonscript mehr...

      Wenn du - wie es zum sauberen Stil gehört - alle Variablen vor der Verwendung erst mal initialisierst und mit einem Default Wert belegst, hast du das Problem auch nicht mehr und hast sogar noch weniger Schreibarbeit:

      $log = false

      #[...]

      if($passwort == "abc")
      {
        $log = "true";
      }

      Oder haltet ihr dies für eine schlechte Idee?

      Ja.

      Da stimme ich zu - ich würde das Script als eine "Pille danach" bezeichnen - hilft schon, aber ist eben der umständliche und auf Dauer sicher auch nicht richtige Weg.

      Versuchs mal über die .htaccess:

      php_flag register_globals [on|off]

      Das geht nur, wenn PHP als Apache Modul geladen wird und die entsprechenden Rechte in der httpd.conf gegeben sind. Die meisten Provider setzen jedoch die CGI Version von PHP ein, da gehts so: Ein Datei names php.ini im Ordner anlegen und

      register_globals = off

      reinschreiben, siehe auch PHP Manual, Kapitel Runtime Configuration.

      MfG, Dennis.

      --
      Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
      Sinnvolles Zitieren: Man zitiert nur Teilsätze des Vorposters auf die man sich bezieht! Nicht einfach alles.
      1. Hi,

        Da stimme ich zu - ich würde das Script als eine "Pille danach" bezeichnen - hilft schon, aber ist eben der umständliche und auf Dauer sicher auch nicht richtige Weg.

        oder alternativ:

        $log = ($passwort == "abc");

        Das geht nur, wenn PHP als Apache Modul geladen wird und die entsprechenden Rechte in der httpd.conf gegeben sind.

        bei mir geht's auf dem Server ;-) Ist also reine Glückssache...

        E7