NeWorld

register globals pavojus

by neworld on Rgp.13, 2007, under php, Programavimas, Sagumas

Šiandien parašysių apie šitą pavojų. Kas tai galite pažiūrėti čia: http://www.php.net/register_globals

Iš pažiūros tai gal ir patogus dalykas, tačiau patariu niekam nenaudoti jo. Juolab jog ateities php versijos šio palaikymo neturės. Panagrinėsiu du pavojingus atvejus ir būda kaip tai ištaisyti.

Taigi pirmasis atvejąs:

Tarkime turime autorizacijos kodą:

admin.php:
[code lang="php"] if (($name=="admin") and ($psw=="Niekas nezino")) {
$autorization=true;
}

if ($autorization==true) {
define("CHECH","Tikras");//padarom konstantą kad control.php būtų garantuotas jog jis yra includinamas iš čia
include('control.php');
} else {
die('Neturite teisių');
}
?>[/code]

Kodas labai paprastas. Taigi kas būtų jeigu naršyklėje parašytume “admin.php?autorization=1″? Ogi pirma kodo dalis šios reikšmės nepakeistų o antroje būtų lyg jungtusi ir adminas. Šita problema išsipręstų, jeigu po pirmojo if sakinio padėtume “else { $autorization=false; }”. Tačiau, žinom jog kuo trumpesnis php kodas, tuo jis sgreičiau veikia, tad stengiamės naudoti pirmąjį variantą, tiesa?

O dabar antrasis variantas:

kodas.php
[code lang="php"] if (is_num($_POST['num']) {
$numeris=$_POST['num'];
}
$_SESSION['numeris']=$numeris;
?>[/code]

Atrodo visai gražus, tavrkingas saugus kodas. Jug patikrinam ar $_POST['num'] yra numeris. Tačiau su register globals mes vistiek galime i sesiją įrašyti belekokią reikšmę

Čia dar niekai palyginus kiek galima pridirbti su sesijom, nes sesijos kintameji irgi tapa kintamaisiais.

Taigi kaip apsisaugoti.

Pirma taisyklė niekada nenaudoti register globals.
Antra taisyklė: jeigu serveris vis dėlto palaiko šį dalyką, ir jūs niekaip negalite jo išjungti, tada visus sesijos kintamųjų pavadinimus įsivardinkite pavadinimais, kurių visam kode nanaudosite kaip kintamųjų. Sakykim $_SESSION['mysession_prisijungimas']; Abejoju ar visam kode panaudosite $mysession_prisijungimas, be to hackeriams baveik neįmanoma atspėti šio derinio.
Tada scripto pradžioje įsidėkite šį kodą:

[code lang="php"]if (ini_get(register_globals)) // If register_globals is enabled
{ // Unset $_GET keys
foreach ($_GET as $get_key => $get_value) {
if (ereg('^([a-zA-Z]|_){1}([a-zA-Z0-9]|_)*$', $get_key)) eval("unset(\${$get_key});");
} // Unset $_POST keys
foreach ($_POST as $post_key => $post_value) {
if (ereg('^([a-zA-Z]|_){1}([a-zA-Z0-9]|_)*$', $post_key)) eval("unset(\${$post_key});");

} // Unset $_REQUEST keys
foreach ($_REQUEST as $request_key => $request_value) {
if (ereg('^([a-zA-Z]|_){1}([a-zA-Z0-9]|_)*$', $request_key)) eval("unset(\${$request_key});");
}
}[/code]

Šis kodas panakins visus kintamuosius sukurtus per register globals (išskyrus sesijos kintamuosius).

Jei visdėlto negalite vadovautis pirma ir antra taisyklė, tai tada:

Niekada nenaudokite 3party kodo (nes hackeriai tiksliai žinos visas spragas paliktus register globals).
Niekam nedalinkite savo kodo.
Stenkitės kurti savo unikalius pavadinimus kintamiesiems.
Stenkitės rašyti pilnas salygas, kad esant klaidingom reikšmėm, kintamieji pasieksitų neprisklausomai nuo register globals
Taip pat vadovaukites antros taisyklės pirma dalimi.

Taigi, jeigu šis tekstas privers bent 1% perkaičiusių žmonių atsisakyti šio dalyko, reiškias man pavyko.


18 Comments for this entry

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!