PHP - register_globals
Návody pro C4
Register globals je konfigurační direktiva PHP, může nabývat dvou hodnot - buď zapnuto nebo vypnuto. Pokud je register_globals zapnuté, znamená to, že k proměnným z odeslaných formulářů, k proměnným v URL a jiným podobným proměnným (např. z cookies) je možné přistupovat přímo přes název proměnné, např. přes $heslo. Když je register_globals vypnuté, tak je možné přistupovat jen přes superglobální pole, např. přes $_POST["heslo"], $_GET["heslo"], $_COOKIES["heslo"] nebo $_SERVER["heslo"] (pokud je zapnutá direktiva register_long_arrays, tak lze k proměnným přistupovat ještě jedním alternativním způsobem, ten je ale zastaralý).
Příklad s proměnnou v URL
Např. na webu www.c4.cz bude umístěn skript test.php. Do internetového prohlížeče zadáte adresu (URL):
http://www.c4.cz/test.php?vstup=sport
Obsah skriptu test.php může být následující:
<?php // vypise Test1, pokud register_globals = On (zapnuto) if($vstup == "sport") echo "Test1<br />;\n"; // vypise Test2 nezavisle na nastaveni register_globals // pristupuje k promenne pres superglobalni pole $_GET if($_GET["vstup"] == "sport") echo "Test2<br />;\n"; ?>
Příklad s proměnnou z formuláře
Dalším typickým příkladem, kdy se projevuje nastavení register globals, je zpracování údajů z odeslaného formuláře. Nechť je součástí internetové stránky jednoduchý formulář na vyplnění jednoho textového pole:
<form method="post" action="/test.php"> <p> Text: <input type="text" name="textove_pole" value="" /><br /> <input type="submit" value="Odeslat" /> </p> </form>
Po odeslání webového formuláře dojde ke zpracování skriptem test.php, který může vypadat takto:
<?php // vypise obsah promenne, pokud register_globals = On (zapnuto) echo "Obsah: $textove_pole<br />\n"; // vypise obsah promenne nezavisle na nastaveni register_globals // pristupuje k promenne pres superglobalni pole $_POST echo "Obsah: $_POST[textove_pole]<br />\n"; ?>
Register globals mějte vypnuté
Vypnuté register globals (tedy že proměnné budou dostupné jen přes superglobální pole $_GET, $_POST, ..) je lepší variatna z následujících důvodů:
- Je to bezpečnější. Weby se zapnutým register_globals jsou snázeji zneužitelné (důvody jsou uvedeny níže).
- V PHP 6 bude register_globals vypnuté a nebude možné ho zapnout. Když budete vytvářet skripty, které budou spoléhat na zapnuté register_globals, takové skripty určitě nepoběží na PHP 6.
Na PHP 5 serverech je register_globals vypnuté (lze na požádání přenastavit, což ale z výše uvedených důvodů nedoporučujeme). Aktuální nastavení lze jednoduše zjistit pomocí funkce ini_get().
Proč je nebezpečné mít register_globals zapnuté?
Zajisté si kladete otázku, proč je to tak nebezpečné mít zapnuté register globals. Zapnuté register_globals totiž umožňují útočníkovi přidat novou globální proměnnou s libovolnou hodnotou a pokud skript korektně neinicializuje proměnné, tak tím může ovlivnit běh skriptu. Podívejme se na jednoduchý příklad. Řekněme, že HTML kód přihlašovacího formuláře do administrační sekce vašeho webu vypadá následovně:
<form method="post" action="http://www.c4.cz/admin.php"> <p> Jmeno: <input type="text" name="jmeno" value="" /><br /> Heslo: <input type="password" name="heslo" value="" /><br /> <input type="submit" value="Odeslat" /> </p> </form>
PHP skript admin.php má tento obsah:
<?php if($jmeno == "admin" && $heslo == "d83jFsTsz2") { $vstup_povolen = 1; } if(!$vstup_povolen) { echo "Bylo zadano chybne heslo. Vratte se zpet.\n"; exit; } ?> <h1>Administracni sekce</h1> ...
Jedná se o začátek PHP skriptu, který zpracovává hodnoty přihlašovacího formuláře. Skript spoléhá na zapnuté register_globals a zároveň není korektně inicializovaná proměnná $vstup_povolen. Útočníkovi nyní stačí, aby do internetového prohlížeče zadal adresu:
http://www.c4.cz/admin.php?vstup_povolen=1
A získá tak přístup do administrační sekce vašeho webu, aniž by znal správné přihlašovací jméno a heslo.
Problém by šlo vyřešit snadno, stačilo by do skriptu admin.php na začátek přidat:
<?php $vstup_povolen = 0; ...
Můžete namítnout, že vám se nic takového nemůže stát, že si při psaní php skriptů dáváte pozor a proměnné vždy korektně inicializujete. U větších projektů jako je např. Joomla, které se skládají z velmi mnoha php skriptů, které jsou navíc různě inkludovány do sebe, je téměř nemožné zamezit všem chybám ohledně nedostatečné inicializace proměnných a proto je důležité, aby register_globals byly vypnuté a nehrozilo zneužití. Uvědomte si, že stačí jedna taková drobná chybka (zapomente inicializovat proměnnou) a následky zneužití mohou být velmi závažné, např. útočník může získat přístup do chráněné sekce webu, může dojít k zneužití skriptu k rozesílání spamu, útočník může získat hesla k databázím nebo může zcela ovládnout web a např. upravovat stávající skripty a nebo si nainstalovat svoje.
Jak předělat skripty, aby fungovaly pro vypnuté register globals?
Pokud máte skripty, které jsou vytvořené pro zapnuté register_globals, lze je poměrně jednoduše předělat, aby fungovaly s vypnutými register globals. Vezměme jako příklad výše uvedený skript admin.php, který zpracovává údaje (jméno a heslo) z přihlašovacího formuláře. V tomto skriptu jsou proměnné $jmeno a $heslo, které díky zapnutým register_globals obsahují data z formuláře. Stačí na začátek skriptu dát následující řádky:
<?php $jmeno = $_POST["jmeno"]; $heslo = $_POST["heslo"]; ...
Tím dosáhnete toho, že proměnné $jmeno a $heslo budou obsahovat data zadaná do formuláře i po vypnutí register_globals. Obecný postup je tedy takový, že všem proměnným, které spoléhají na inicializaci pomocí register globals, na začátku skriptu přiřadíte obsah ze superglobálních polí. Nejčastěji používaná superglobální pole jsou:
- $_GET - proměnné z URL
- $_POST - proměnné z formulářů
- $_COOKIE - proměnné z cookies uložených na klientském počítači
- $_SERVER - různé systémové proměnné, např. $_SERVER["REMOTE_ADDR"] je ip adresa počítače, který natahuje skript
Související odkazy
- http://www.php.net/manual/en/ini.core.php#ini.register-globals - originální dokumentace k register_globals (v angličtině)
- http://www.php.net/manual/en/security.globals.php - register globals a bezpečnost (v angličtině)
- http://www.php.net/manual/en/language.variables.predefined.php - předdefinované proměnné zejména superglobální pole (v angličtině)
- http://www.php.net/manual/en/reserved.variables.php - podrobný popis předdefinovaných proměnných, zejména superglobálních polí (v angličtině)
Diskuzní fórum pro článek PHP - register_globals
Nové diskuzní téma můžete založit v sekci PHP, MySQL.
Změny a kontroly
K dispozici je kompletní přehled všech změn a kontrol v tomto návodu.
PHP - register_globals
Publikace: | 27.8.2007 |
Přehled změn a kontrol |
Diskuzní fórum
- Webové aplikace
- Tvorba web stránek
- PHP, MySQL