Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




PHP Sola

Slovena


PHP Sola (4. del)

V prejsnjem delu smo se naučili kako črpamo podatke iz zunanjih virov. Iz podatkovne baze, datoteke ali spletnega obrazca. Vendar tem podatkom vedno ne moremo zaupati. Pogledali si bomo kako preveriti podatke in zavarovati aplikacijo pred morebitnimi napadi. Prav tako bomo omenili, kako nalozimo datoteko preko obrazca in podobne naprednejse tehnike.

(Ne)varnost obrazcev

Vsi podatki, ki je vnese uporabnik preko spletnih obrazcev so potencialni nevarni podatki. Osnovno pravilo je, da programer ne sme zaupati uporabniku vnesenih podatkov, ampak mora le-te preveriti. Eden izmed najbolj razsirjenih napadov je SQL injection. To je napad s katerim napadalec spreminja SQL stavek in posledično dobi iz podatkovne baze podatke kateri mu niso namenjeni. Poglejmo si preprost primer.



<?php

mysql_connect('localhost', 'root');

$sql = 'SELECT priimek FROM uporabniki WHERE ime=\''.$_GET['ime'].'\' AND geslo=\''.$_GET['geslo'].'\'';

$r = mysql_query($sql);

$row = mysql_fetch_assoc($r);

echo $row['priimek'];

?>

Kot vidimo sestavimo SQL stavek iz dveh spremenljivk, ki smo ji dobili preko GET metode. Če bi uporabnik zahteval sledečo skripto: /skripta.php?ime=janez&geslo=kranjski. Iz tega dobimo veljavni SQL stavek. Prvi problem, ki se pojavi je, če ime vsebuje posebne znake kot je enojni narekovaj - '. Kot 21521x2316v vemo morajo biti nizi obdani z enojnim ali dvojnim narekovajem. V nasem primeru je niz obdan z enojnim in ker ime vsebuje enojni narekovaj, PHP smatra, da je tukaj konec niza. Preostanek pa zeli ignorirat, ampak ker ni konec niza javi napako. To je prva nevarnost, kajti napadalec lahko vidi pot skripte, vrstico in se druge podrobnosti. Prav na ta način se da izvesti SQL napad. Torej lahko napadalec po svoji zelji spreminja SQL stavek. V nasem primeru kliče skripto na sledeč način: /skripta.php?ime=admin'#. Kot vidite mu gesla niti ni potrebno vedet, da bo izpisal priimek uporabnika admin. Zraven imena se je na koncu enojni narekovaj, ki pove konec niza, znak # pa pomeni komentar, torej konec SQL stavka v tej vrstici. Tako napadalec doseze, da se geslo nikdar ne preverja.

Vidimo, da sploh ni tako tezko izvesti SQL injection napada. Zato mora programer poskrbeti za varnost in nikdar zaupati uporabniku, kaj vnese. Torej mora te podatke nekako filtrirati. Stevila filtriramo na precej preprost način. Kot vemo sta spremenljivki $_GET in $_POST polji nizov. Torej vrednosti, ki predstavljajo stevila pretvorimo v zeleni tip. Za celo stevilo lahko uporabimo sledeča primera, ki se med seboj ne razlikujeta.

<?php

$id = (int)$_GET['id'];

// ali funkcijo intval

$id = intval($_GET['id']);

?>

S tem zagotovimo, da je spremenljivka $id vedno tipa celo stevilo. V primeru da je GET id neveljavno stevilo se pretvori v 0.

Več dela imamo z nizi. Najprej moramo paziti kaksne podatke dobimo. Namreč PHP nam omogoča, da ze sam avtomatsko obdela vse vrednosti, ki pridejo od uporabnika in jim doda znak \. Če imamo to vklopljeno lahko preverimo s funkcijo get_magic_quotes_gpc(), katera vrne pravilno v primeru, če PHP obdela vrednosti. Takrat moramo preden izpisujemo podatke ali sestavljamo SQL stavek te vrednosti očistiti s pomočjo funkcije stripslashes(). Nato uporabimo funkcijo mysql_real_escape_string(), katera prejme kot argument niz in vrne varen niz, iz katerega lahko sestavimo SQL stavek. Tako bi v nasem primeru zgledala varna skripta.

<?php

mysql_connect('localhost', 'root');

if ( get_magic_quotes_gpc() )

$_GET['ime'] = mysql_real_escape_string($_GET['ime']);

$_GET['geslo'] = mysql_real_escape_string($_GET['geslo']);

$sql = 'SELECT priimek FROM uporabniki WHERE ime=\''.$_GET['ime'].'\' AND geslo=\''.$_GET['geslo'].'\'';

$r = mysql_query($sql);

$row = mysql_fetch_assoc($r);

echo $row['priimek'];

?>

Na začetku očistimo niz in ga pripravimo na izpis, nato spremenljivki spustimo skozi funkcijo mysql_real_escape_string, preden sestavljamo SQL stavek. Seveda bi lahko funkcijo klicali kar v naslednji vrstici, kjer sestavljamo SQL stavek. To nam pride prav v primeru, če se za tem potrebujemo spremenljivki. Slabost tega je slabsa preglednost in dolga vrstica iz katere se na prvi pogled ne da razbrati, kaj vsebuje.

Pomembno je, da ne pozabimo preveriti ali nam ze sam PHP obdela niz, kajti v tem primeru bomo imeli dvakrat obdelan niz, kar spet ni zelen rezultat in lahko prav tako vodi k varnostnimi luknjami.

Delo z obrazci

V prejsnjem delu smo spoznali kako preberemo podatke iz spletnega obrazca. Sedaj, ko poznamo tudi (ne)varnosti obrazcev lahko te podatke začnemo zares uporabljati. Nadaljevali bomo primer dnevnika iz prejsnjega dela sole. Naredili bomo obrazec in skripto, ki dodaja dnevniske vpise. Poglejmo si kodo.

<?php

if ( get_magic_quotes_gpc() && is_array( $_POST ) )

@reset( $_POST );

$msg = @$_POST['msg'];

if ( !empty( $msg ) ) else

mysql_connect( 'localhost', 'matjaz', '3' );

mysql_select_db( 'planetpc' );

mysql_query( 'INSERT INTO blog (vsebina,datum) VALUES ("' . mysql_real_escape_string( $msg ) . '", "' . date( 'Y-m-d G:i:s', $date ) . '")' );

echo 'Sporočilo dodano<br><br>';

?><form action="blog_add.php" method="POST">

Datum:<br><input type="text" name="date" value="<?php echo date( 'Y-m-d G:i' ); ?>"><br>

Sporočilo:<br><textarea name="msg" rows="5" cols="30"></textarea><br>

<input type="submit" value="Dodaj">

</form>

Najprej preverimo ali ze sam PHP obdela vrednosti in jih ustrezno vrnemo v originalne vrednosti. V nasem primeru pogledamo samo POST vrednosti, saj nas druga ne zanima. Nato si naredimo začasno spremenljivko v kateri je vsebina polja. Preverimo ali vsebina polja ni prazna (pozor, funkcija empty smatra tudi vrednost 0 kot prazno). Če je obrazec potrjen in je vsebina dnevnika vpisana nadaljujemo s vpisovanjem. Preverimo ali je vpisan datum in ga ustrezno pretvorimo. V naslednjih vrsticah se povezemo z bazo in dodamo zapis v bazo.Vrednost vsebine dnevnika obdamo s funkcijo, ki zavaruje niz pred napadi, datum pa smo pretvorili ze prej in ga zato lahko v ustreznem formatu vpisemo brez strahu. Na koncu je se obrazec za vpis dnevnika.

Vidimo lahko da se vrednost polja datum vedno izpolni, saj smo določili da se izpise datum v vrednost polja. Pozorni moramo biti na if stavek, kateri odloči ali se naj izvede vpisovanje v bazo. Zadeva pri delu z obrazci se malo zakomplicira oziroma je potrebno napisati več kode, kot le pri izpisovanju vrednosti. Vendar ob upostevanju navedenih pravil mora biti vsaka aplikacija varna.

Prenos datoteke

PHP nam omogoča prenos datoteke na streznik in morebitno hrambo le te na strezniku. Opozoriti je potrebno, da je moznost nalaganja datotek in shranjevanje le teh morebitna varnostna luknja, saj lahko napadalec nalozi zli kodo in to izvede. Zatorej je potrebno preden to omogočimo poskrbeti za varnost. Dokler omogočamo nalaganje slik ipd. so stvari preproste, pri nalaganju npr. datoteko s končnico .php pa lahko naredimo varnostno luknjo. Paziti moramo da uporabnik ne more dostopati do te datoteke direktno, saj lahko v tem primeru zazene to skripto.

Poglejmo si primer kako naloziti sliko tipa GIF. Najprej obrazec, s katerim poisčemo datoteko na računalniku, ki jo zelimo naloziti.

<form enctype="multipart/form-data" action="upload.php" method="POST">

<input type="hidden" name="MAX_FILE_SIZE" value="100000">

Datoteka: <input name="file" type="file">

<input type="submit" value="Nalozi"></form>

Formi smo spremenili tip kodiranja, tako da lahko nalagamo datoteke. Polje MAX_FILE_SIZE merjeno v bajtih nam pove maksimalno velikost datoteke, ki sme biti nalozena. To polje je zazeleno, saj v primeru da je datoteka prevelika se niti ne izvede posiljanje datoteke na streznik. Polje s katerim poisčemo datoteko je po HTML standardu tipa file. Poglejmo se skripto, ki preveri pravilnost datoteke in jo shrani na streznik.

<?php

if ( isset( $_FILES['file'] ) && $_FILES['file']['size'] > 0 )

if ($_FILES['file']['size'] > 100000)

$uploadfile = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . basename( $_FILES['file']['name'] );

if ( move_uploaded_file( $_FILES['file']['tmp_name'], $uploadfile ) ) else

?>

Najprej preverimo ali je bila skripta poklicana preko obrazca in je bila izbrana datoteka večja od 0 bajtov. Nato preverimo ali je tip datoteke GIF slika. V primeru da ni, to izpisemo in končamo izvajanje skripte z die funkcijo. Enako preverimo za velikost datoteke. Nato si naredimo spremenljivko katera vsebuje polno pot do skripte in ime datoteke. V nasem primeru se slika shrani v isti direktorij kot je skripta. Funkcija move_uploaded_file premakne datoteko iz začasne mape na zelen cilj in vrne pravilno če datoteka obstaja oziroma je bila datoteka nalozena preko obrazca, v nasprotnem primeru vrne nepravilno. Glede na to tudi izpisemo rezultat. S tem smo uspesno nalozi datoteko na streznik. Če datoteko zelimo le prebrati in obdelati njeno vsebino, lahko dostopamo do nje iz začasne mape. Ime datoteke izvemo preko $_FILES['file']['tmp_name'] spremenljivke.

Naprednejse tehnike

Oglejmo si se nekaj naprednejsih tehnik pri delu s PHP-jem. Prvo kar bomo omenili je vključevanje datotek. To nam pride prav na primer, kadar uporabljamo določene funkcije v različnih datotekah. Te datoteke razbijemo na več manjsih in smiselno v njih zdruzimo skupne funkcije. Poudariti je treba doseg spremenljivk.Če vključimo datoteko v svojo skripto, vsebina postane del skripte, kot da bi bila v tej datoteki. Torej so globalne spremenljivke skupne. Funkciji s katerima vključimo datoteko sta include in require. Razlika med njima je le kako se obravnavajo napake. Require sprozi ob napaki napako, ki konča izvajanje skripte, medtem ko include vrne le opozorilo in se nadaljuje izvajanje. Poglejmo si primer. Datoteka vars.php

<?php

$barva = 'zelena';

$sadje = 'jabolka';

?>

Datoteka primer.php

<?php

echo "$barva $sadje";

include 'vars.php';

echo "$barva $sadje";

?>

Kot vidimo se prvič ne izpise nič, saj je vsebina spremenljivk prazna oziroma nista niti definirani. Po vključitvi datoteke spremenljivki dobita vrednost in se izpise njuna vsebina.

Ena izmed tehnik, katere se posluzujejo PHP programerji je tudi uporaba @ operaterja. S pomočjo tega operaterja izklopimo javljanje napak in tako preprečimo, obiskovalcu izpis kakrsnekoli informacije kaj, kje in zakaj se je zgodila napaka.

<?php

echo @filesize('datoteka_ne_obstaja');
?>

V tem primeru ker datoteka ne obstaja ne bo izpisane nobene napake, saj smo za določeno funkcijo izklopili javljanje le teh. Prav tako lahko izklopimo javljanje napak za spremenljivke, na primer kadar indeks polja ne obstaja.

PHP nam omogoča da lahko vsakrsno napako obravnavamo sami. Na začetku skripte podamo sledečo funkcijo set_error_handler, s katero določimo ime nase funkcije, ki bo skrbela za napake. Navedena funkcija mora imeti vsaj dva argumenta. Prvi je stevilka napake, drugi pa sporočilo. Dodani so se lahko trije neobvezni argumenti. Napake lahko prozimo tudi ročno s pomočjo funkcije trigger_error, kateri podamo tekst napake in neobvezno kot drugi argument tip napake. To nam pride prav ob morebitni napačni vrednosti v obrazcu.

Naslednjič si bomo ogledali kako upravljamo s sejami, uporabljamo piskotke in na kratko se bomo dotaknili objektnega programiranja v PHP jeziku.


Document Info


Accesari: 1795
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )