torek, februar 05, 2008

Magic Quotes v PHP

Magic quotes je proces v PHP, ki avtomatično ubeži enojnim in dvojnim narekovajem ter poševnici nazaj in NULL znaku. To pomeni, da bo ta proces avtomatično spremenil nek niz tako, da bo vsem zgoraj omenjenim znakom dodal spredaj poševnico nazaj (\). Znak, ki ima pred seboj poševnico nazaj, imenujemo ubežni znak in ima drugačen pomen kot znak, ki poševnice nazaj pred seboj nima.

Zakaj potrebujemo magic quotes?
Predpostavimo, da smo izdelali spletno stran z novicami, kjer imamo tudi obrazec preko katerega lahko obiskovalci strani dodajo svoj komentar. Kaj se zgodi, če v obrazec obiskovalec zapiše
Uporabi iskalnik Mat'Kurja?

Problem se pojavi, ko želimo zgornji komentar vpisati v bazo. Vpis v bazo opravimo z SQL stavkom, npr:
$sql = "INSERT INTO komentar SET vsebina = '$oddan_komentar'";

Kot vidimo, se niz znakov v SQL ukazu obda z enojnim narekovajem. Prvi označuje začetek niza, drugi pa konec. Kaj pa v našem primeru, ko že sam komentar vsebuje enojni narekovaj? Ja, to pokvari SQL stavek, saj baza podatkov prehitro zaključi SQL ukaz, ki ga vidi kot:
$sql = "INSERT INTO komentar SET vsebina = 'Uporabi iskalnik Mat'Kurja'"
Le odebeljen del SQL stavka zgoraj je sintaktično pravilen, preostali del, torej besedica Kurja'" pa sedaj povzroči napako.

Kako odpraviti težavo?
Problem odpravimo, da ubežimo enojnemu narekovaju za besedo Mat. To naredimo tako, da pred enojni narekovaj zapišemo poševnico nazaj z uporabo funkcije addslashes(). SQL ukaz bo tako sintaktično pravilen, saj bo enojni narekovaj, ki ima pred seboj poševnico nazaj, obravnavan kot znak enojni narekovaj in ne kot posebni znak, ki zaključuje SQL ukaz.

Alternativa "ročnemu" načinu je avtomatočni način, to je magic quotes. Ta avtomatično doda nizu ustrezne ubežne znake in tako zavaruje SQL ukaze pred napakami oz. možnimi zlorabami. Nepridipravi bi lahko z uporabo narekovajev zaključili vsebino in dodali zraven še nekaj zlonamerne kode. Ta pomanjkljivost je bolje poznana kot "SQL injection".

Magic Quotes je bil v PHP uveden kot varovalka pred slabo napisano kodo, ki bi omogočala zlorabe.

Obstajajo tri vrste magic quote procesov:
- magic_quotes_gpc, ki doda poševnice nazaj spremenljivkam, ki so PHP skripti poslane preko POST, GET ali COOKIE
- magic_quotes_runtime, doda poševnice nazaj podatkom zunanjega vira kot je datoteka ali baza podatkov
- magic_quotes_sybase, ubeži enojnemu narekovaju tako, da pred njega postavi še en enojni narekovaj (namesto poševnice nazaj)

Kako preverimo, če je magic quotes vključen?

if (get_magic_quotes_gpc()) {
echo "Magic Quotes je vključen.";
}



V primeru, da je magic quotes vključen, moramo vsebino spremenljivke obdelati s pomočjo funkcije stripslashes(), ki odstrani poševnice. Šele nato je primerna za prikaz na zaslonu. Za vpis v bazo pa to ni potrebno, saj baza te znake sama odstrani in pravilno shrani vsebino.

Če naš strežnik podpira PHP starejši od verzije 6, moramo v skripti poskrbeti za preverjanje ali je magic quotes vključen ali ne. Če je vključen, se moramo zavedati, da vsebina lahko vsebuje tudi več poševnic nazaj, ki jih moramo pred izpisom odstraniti. V koliko pa magic quotes ni vključen, pa mora programer sam poskrbeti za varnost skripte, pred izvrševanjem SQL ukazov.