PHP:n vanhoissa versioissa (5.3 ja aiemmat) on haitallinen ominaisuus nimeltä Register Globals: osoitteen parametrit ja lomakkeiden tiedot tulevat suoraan globaaleiksi muuttujiksi, eli esimerkiksi osoitteen lopussa oleva ?id=123 muuttuu suoraan muuttujaksi $id = 123. Tähän liittyy kaksi ongelmaa: ominaisuuden käyttäminen johtaa koodiin, joka ei toimi nykyisillä PHP:n versioilla, ja ominaisuuden olemassaolo voi aiheuttaa tietoturva-aukon tilanteissa, joissa jotain muuttujaa ei ole asetettu. Seuraavassa on esimerkki mahdollisesta tietoturva-aukosta:
<?php if ($_COOKIE["kayttajan_istunto"] == hae_adminin_istunto()) { $admin = true; } if ($admin) { system("rm -rf /"); # Vaarallista koodia vain ylläpitäjälle! }
Nyt $admin-muuttujassa on arvo true, jos ylläpitäjä on kirjautunut; muuten muuttujaa ei ole määritelty. Hakkeri voi lisätä osoitteen perään arvon ?admin=1, jolloin Register Globals asettaa muuttujalle arvon 1 ja hakkeri pääsee ylläpitäjäksi.
Ongelman oikea ratkaisu on tietenkin alustaa jokainen muuttuja ennen käyttöä. Silloin hakkeri voi syöttää, mitä haluaa, mutta $admin on varmasti aina aluksi false.
<?php $admin = false; if ($_COOKIE["kayttajan_istunto"] == hae_adminin_istunto()) { $admin = true; } if ($admin) { system("rm -rf /"); # Vaarallista koodia vain ylläpitäjälle! }
Toinen ratkaisussa auttava asia on säätää PHP:n asetukset oikein: poistaa käytöstä register_globals ja ottaa käyttöön PHP:n huomautukset puuttuvista muuttujista.
Kolmas konsti – jos asetuksia ei voi muuttaa eikä taito riitä kaikkien muuttujien alustamiseen – on laittaa aivan sivun alkuun koodi, joka poistaa kaikki ylimääräiset muuttujat. Koodi voi näyttää vaikka tältä:
if (!function_exists("undoRegisterGlobals") && ini_get("register_globals")) { function undoRegisterGlobals() { foreach (array_keys($GLOBALS) as $key) { if (!in_array($key, array("GLOBALS", "_GET", "_POST", "_FILES", "_COOKIE", "_REQUEST", "_SESSION", "_SERVER", "_ENV"))) { unset($GLOBALS[$key]); } } } undoRegisterGlobals(); }
Nykyisissä PHP:n versioissa (5.4 ja uudemmat) ongelmaa ei onneksi ole enää lainkaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.