Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Register Globals pois käytöstä

Metabolix [10.04.2011 20:30:39]

#

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta