Vypnutí register_globals

Školení, která pořádám

Direktiva register_globals způsobuje, že z dat, která se přijmou od uživatele, se automaticky vytvoří globální proměnné, což při špatné inicializaci vlastních proměnných může vést k podstrčení jejich hodnot. Tuto direktivu je proto vhodné vypnout. Pokud nemůžete měnit konfiguraci serveru, můžete na začátek skriptů přidat následující kód, který již jednou zaregistrované proměnné zase odregistruje:

<?php
/** Odregistrování proměnných zaregistrovaných direktivou register_globals
* @return null upraví pole $GLOBALS
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function deregister_globals() {
    static $allowed = array('GLOBALS', 'argc', 'argv', '_GET', '_POST', '_COOKIE', '_REQUEST', '_FILES', '_SERVER', '_ENV', '_SESSION');
    foreach ($GLOBALS as $key => $val) {
        if (!in_array($key, $allowed)) {
            unset($GLOBALS[$key]);
        }
    }
}
if (ini_get("register_globals")) {
    deregister_globals();
}
?>

Pokud správně inicializujeme proměnné, tak direktiva register_globals bezpečnostní riziko nepředstavuje. Ale vzhledem k tomu, že PHP nenabízí žádný mechanismus, jak správnou inicializaci proměnných vynutit (ochranu nenabízí ani úroveň chyb E_NOTICE), je vypnutí této direktivy u neprověřených projektů více než vhodné.

Přijďte si o tomto tématu popovídat na školení Bezpečnost PHP aplikací (13.6.2018 - 14.6.2018, Praha).

Jakub Vrána, Řešení problému, 6.12.2006, diskuse: 16 (nové: 0)

Diskuse

ikona dgx:

Jen doplním, že plně funkční to bude tehdy, bude-li funkce volána až po otevření session (session_start), nikoliv před.

numero:

K čemu to bude dobré?

ikona Jakub Vrána OpenID:

V článku to je napsané - pokud používám kód, u kterého nemám jistotu, že není náchylný k podstrčení proměnných, a zároveň nemohu dostatečně ovlivnit konfiguraci serveru.

Vita:

Kdy se má tato funkce použít? Pokud ji použiju ještě před vykonánaním jakéhokoliv skriptu, tak mi to hlásí že nezná ani funkce ani proměnné které si načítám z tříd z jiných souborů. Děkuji

ikona MiSHAK:

hned za
<?php
nebo pokud používáš session pak za
<?php
session_start
()

Vita:

a to musim dat do kazdeho souboru zvlast? Nebo to staci dat do nejakeho konfiguracniho souboru pro vsechny.

ikona Jakub Vrána OpenID:

Stačí to samozřejmě dát do nějakého společného souboru.

Vita:

No a to je prave to co mi nejak nejde kdyz to tam dam tak mi php hlasi ze nezna funkce atd... Veskere funkce a promene mam v tridach a kdyz si tento kod dam do konf. souboru tak mi to pak dela tyto problemy :-(. Na svem serveru mam samozrejme vyple registr_globals. Ale na hostingu neni a tak bych to chtel mi projistotu osetreno timto figlem. Nevite v cem by mohl byt problem?

ikona MiSHAK:

OT: to zvýrazňování PHP kódu by mělo ještě testovat jestli je někde vůbec konec (?>)

ikona Jakub Vrána OpenID:

Používá se na to prostá funkce highlight_string(). Mimochodem skript značkou ?> ukončen být nemusí.

Techi:

Co starší asociativní pole jako HTTP_GET_VARS atd. Jinak superglobální pole _FILES se při register_globals=1 přece nepřepisuje jako globální proměnná

ikona Jakub Vrána OpenID:

Starší pole doporučuji nepoužívat, proto se klidně můžou odnastavit...

Z položek v poli $_FILES se globální proměnné také vytváří, i když trochu jinak. Ale i kdyby to tak nebylo, tak příspěvek postrádá smysl, protože uvedení '_FILES' v seznamu znamená, že se tato proměnná neodnastaví.

Ing. Jaroslav Křepelka:

Mám problém.
Na svých webových stránkách jsem použil formulář, který
má sloužit k zasílání textů na server po stisknutí
tlačítka input.
Když jsem to dal na server tka to nefunguje.
Dotázal jsem se administrátora - ten odpověděl, že je vypnuta direktiva registr_globals.
Jak to mám udělat, abych text, který napíše klient
do formuláře dostall na server i když je ta direktiva
vypnutá. Jde to vůbec nějak udělat?

Štěpán Svoboda:

Ve skriptu na serveru, který zpracovává data z onoho formuláře, musíte použít namísto názvu proměnné $vzkaz proměnou $_POST['vzkaz'] resp. $_GET['vzkaz'] podle toho jakou metodou odesíláte formulář.

O tomto jsou po internetu celé litanie.

Jde o to, že vaše hodnota z formulářového políčka se nezaregistruje automaticky jako $vzkaz, ale místo toho je k nalezení v superglobální proměnné $_POST resp. $_GET.

Snad to takhle postačí, jinak doporučuji k přečtení třeba

http://interval.cz/clanky/superglobalni-promenne-v-php/

ikona Medhi:

Podrobně to vysvětluji zde, snad to pomůže http://vseohostingu.cz/register-globals

vandy:

Tenhle článek je super. Můj web běží na humlak.cz na serveru je ale direktiva reg globals nastavena na on a nemohu se dostat do konfigu php.ini. Problém je v tom, že tvůj skript mi nefunguje :(

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.