1. Erläuterungen
Ist magic_quotes_gpc aktiviert, werden alle doppelten und einfachen Anführungszeichen in Benutzereingaben automatisch mit Schrägstrichen versehen („escapet”). Der Sinn dahinter ist, SQL-Injections vorzubeugen, denn in SQL werden genau diese Zeichen verwendet, um den Anfang und das Ende von Attributwerten zu markieren. Setzt man etwa die Benutzereingabe
ohne weitere Prüfung und ohne Escaping in das SQL-Statement
ein, dann wird daraus tatsächlich das folgende — explizit nicht erwünschte — SQL-Statement:
Nicht erwünscht ist es, da das 1=1 auf alle Benutzer zutrifft und daher auch alle eingeladen werden, völlig unabhängig davon, ob tatsächlich das richtige Passwort übergeben wurde. Mit aktiviertem magic_quotes_gpc würden die einfachen Anführungszeichen escapet werden. Die Eingabe würde daher zu „example\' OR 1=1 OR password=\'” abgewandelt werden. Die Datenbank würde dementsprechend nach einem Benutzer mit Namen „example_user” und dem exakten Passwort „example' OR 1=1 OR password='” (als ein String) suchen, der aller Wahrscheinlichkeit nach nicht existieren dürfte.
Der Nachteil ist, dass für jede Benutzereingabe, die direkt auf der Seite dargestellt werden soll, das Escaping wieder rückgängig gemacht werden muss, was unnötige Code-Zeilen benötigt und zudem Performance kostet. (Gleiches gilt für alle anderen Verwendungszwecke, bei denen einfache und doppelte Anführungszeichen nicht escapet werden sollen.) Zudem schützt es nicht vor allen SQL-Injection-Attacken und wiegt den Entwickler daher in falscher Sicherheit. Aus diesen Gründen läuft die Unterstützung von magic_quotes_gpc aus. In Altsystemen ist es aber häufig noch aktiviert. Die nachfolgende Funktion kann verwendet werden, um es gezielt zu deaktivieren.
2. Funktion zum Deaktivieren von magic_quotes_gpc
Das nachfolgende Beispiel zeigt die Funktion deactivateMagicQuotes(), welche die Auswirkungen von magic_quotes_gpc für alle Werte aus $_GET, $_POST und $_COOKIE rückgängig macht.
<?php error_reporting(E_ALL); // Macht magic_quotes_gpc rueckgaengig function deactivateMagicQuotes() { $_POST = stripslashesDeep($_POST); $_GET = stripslashesDeep($_GET); $_COOKIE = stripslashesDeep($_COOKIE); } // Diese Funktion wird auf jeden Wert angewandt function stripslashesDeep($value) { return is_array($value) ? array_map('stripslashesDeep', $value) : stripslashes($value); } // Beispieldaten $_GET = array( addslashes('bla_example') => addslashes('this is \'example\' data'), addslashes('beispiel') => addslashes('"beispielhafte" daten'), addslashes('arr') => array( 'k1' => 'beispiel', 'k2' => 'test \'test\' test' ) ); deactivateMagicQuotes(); var_dump($_GET); ?>
array(3) { ["bla_example"]=> string(22) "this is 'example' data" ["beispiel"]=> string(21) ""beispielhafte" daten" ["arr"]=> array(2) { ["k1"]=> string(8) "beispiel" ["k2"]=> string(16) "test 'test' test" } }
3. magic_quotes_gpc auch bei Schlüsseln deaktivieren
Die vorherige Funktion wird nur auf die Werte der Arrays $_GET, $POST und $_COOKIE angewandt. Standardmäßig escapet magic_quotes_gpc aber auch alle Schlüssel dieser Arrays. In der Praxis sollte zwar die vorherige Funktion bedenkenlos ausreichen (da man keine Parameter oder Cookies mit Anführungszeichen im Namen definieren sollte), falls dies aber mal nicht der Fall ist, kann die nachfolgende abgewandelte Version verwendet werden:
<?php error_reporting(E_ALL); function deactivateMagicQuotes() { $_POST = stripslashesDeep($_POST); $_GET = stripslashesDeep($_GET); $_COOKIE = stripslashesDeep($_COOKIE); } function stripslashesDeep($arr) { $out = array(); foreach ($arr as $key=>$value) { $key = stripslashes($key); $value = (!is_array($value) ? stripslashes($value) : stripslashesDeep($value)); $out[$key] = $value; } return $out; } $_GET = array( addslashes('bla"example') => addslashes('this is \'example\' data'), addslashes('beispiel') => addslashes('"beispielhafte" daten'), addslashes('arr') => array( 'k1' => 'beispiel', 'k2' => 'test \'test\' test' ) ); deactivateMagicQuotes(); var_dump($_GET); ?>
array(3) { ["bla"example"]=> string(22) "this is 'example' data" ["beispiel"]=> string(21) ""beispielhafte" daten" ["arr"]=> array(2) { ["k1"]=> string(8) "beispiel" ["k2"]=> string(16) "test 'test' test" } }
4. Prüfen, ob magic_quotes_gpc aktiviert ist
Um den eigenen Code portabler zu gestalten und robuster gegenüber Änderungen an den Einstellungen bezüglich magic_quotes_gpc, sollte immer zunächst überprüft werden, ob magic_quotes_gpc überhaupt aktiviert ist. Andernfalls riskiert man, Schrägstriche zu entfernen, die tatsächlich vom Benutzer eingegeben wurden, da magic_quotes_gpc gar nicht angeschaltet ist. Die Prüfung erfolgt über die Funktion get_magic_quotes_gpc().
<?php if (get_magic_quotes_gpc()) { deactivateMagicQuotes(); } ?>