PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII...

16
VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection ….. Ova lekcija sadrţi: 1.XSS i zaštitu od njega, 2. SQL injectio i zaštitu i 3. Kompletnu registracijsku formu XSS I zaštita PHP 5 Forma ispravnost I provera PHP Forma ispravnost I provera Mislite na prvom mestu na sigurnost kada pravite I obrađujete formu! Ovde ćemo da pokaţemo kako se obraĎujuju PHP forme imajući na umu prvenstveno sigurnost. Baš provera ispravnosti unetih podataka u formu je najvaţnija u zaštiti od hakera i spamera! Neka HTML forma sadrţi razna polja za unos podataka: obavezna I neobavezna, radio dugmad, i submit dugme: Procedura provere forme je sledeća: Polje Pravila za proveru Ime obavezno + mora da sadrži samo slova I praznine E-mail obavezno + Mora da sadrži ispravnu email adresu (sa @ i .) Website Neobavezni. Ako je polje popunjeno, mora da sadrži ispravan URL

Transcript of PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII...

Page 1: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

VII lekcija

Zaštita postojećeg sistema različitim napadima na sistem,

XSS, Sql injection …..

Ova lekcija sadrţi:

1.XSS i zaštitu od njega,

2. SQL injectio i zaštitu i

3. Kompletnu registracijsku formu

XSS I zaštita

PHP 5 Forma ispravnost I provera

PHP Forma ispravnost I provera

Mislite na prvom mestu na sigurnost kada pravite I obrađujete formu!

Ovde ćemo da pokaţemo kako se obraĎujuju PHP forme imajući na umu prvenstveno

sigurnost. Baš provera ispravnosti unetih podataka u formu je najvaţnija u zaštiti od hakera i

spamera!

Neka HTML forma sadrţi razna polja za unos podataka: obavezna I neobavezna, radio dugmad,

i submit dugme:

Procedura provere forme je sledeća:

Polje Pravila za proveru

Ime obavezno + mora da sadrži samo slova I praznine

E-mail obavezno + Mora da sadrži ispravnu email adresu (sa @ i .)

Website Neobavezni. Ako je polje popunjeno, mora da sadrži ispravan URL

Page 2: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Komentar Neobavezno. Višelinijski unos u polje (textarea)

Pol Neophodno. Mora da se selektuje 1 pol od dva ponuđena.

Text polja

Ime, email, i website polja su tekstualni unos , I komentar je polje tipa textarea. Kod HTML

izgleda ovako:

Ime: <input type="text" name="ime">

E-mail: <input type="text" name="email">

Website: <input type="text" name="website">

Comment: <textarea name="comment" rows="5" cols="40"></textarea>

Radio dugmad

Polja za pol su radio dugmad i HTML kod izgleda ovako:

Pol:

<input type="radio" name="pol" value=" ženski "> Ženski

<input type="radio" name=" pol " value=" muški "> Muški

Forma Element

Kod HTML forme izgleda ovako:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Kada je forma sabmitovana , podaci iz forme se šalju post metodom method="post".

Šta je $_SERVER*"PHP_SELF"+ promenljiva?

Promenljiva $_SERVER["PHP_SELF"] super globalna promenljiva koja vrada ime fajla skripta koji se

tog momenta izvršava.

Page 3: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Dakle, $_SERVER["PHP_SELF"] šalje podatke iz sabmitovane forme na istu stranu na kojoj je I

forma,umesto da skoči na neku drugu stranu na kojoj je program za obradu podataka. Ovako,

korisnik će da vidi poruku o greškama na istoj strain na kojoj je I forma.

Šta radi funkcija htmlspecialchars() ?

Funkcija htmlspecialchars() prebacuje specijalne karaktere u HTML entitete. To znači da de HTML

karaktere kao što su < i > da prebaci u &lt; i &gt;. Ovo sprečava napadače da iskoriste kod i da ubace

HTML ili Javascript kod (Cross-site Scripting napadi) u formu.

Sigurnost PHP Forme

Promenljiva $_SERVER["PHP_SELF"] moţe biti iskorišćena od strane hakera!

Ako je PHP_SELF upotrebljen na web stranici onda korisnik moţe da unese kosu crtu- slash (/)

a zatim neke Cross Site Scripting (XSS) komande koje će se izvršiti.

Cross-site scripting (XSS)koristi kompjutersko- sigurnosnu ranjivost koja je karakterističan za Web

aplikacije. XSS omogudava napadačima da ubacuju sa klijentske strane script u Web stranice, koji

posle mogu da vide drugi korisnici.

Pretpostavimo da imamo sledeću formu na stranici pod imenom "test_form.php":

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

sada, ako korisnik unese neki normalni URL u adresnu liniju kao na primer ovu "

http://localhost/pretnjezastita/test_form.php ", gornji kod će biti preveden u sledeće:

<form method="post" action="test_form.php">

Ako korisnik unese sledeći URL u adresnu liniju :

http://localhost/pretnjezastita/test_form.php/%22%3E%3Cscript%3Ealert('mogu_da_te_hakujem_kako

_hocu')%3C/script%3E

U ovom slučaju, gornji kod će ovo da prevede u:

<form method="post" action="test_form.php/"><script>alert(''mogu_da_te_hakujem_kako_hocu

')</script>

Page 4: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Ovaj kod dodaje jedan scriptni tag i alert comandu. I kada se stranica loaduje,kod JavaScript biće

izvršen (I korisnik će videti jedan alert box sa porukom). Ovo je jedan jednostavan I neškodljiv

primer kako PHP_SELF promenljiva moţe biti zloupotrebljena.

Čuvajte se od takvih JavaScript code koji mogu biti dodati unutar <script> taga! Neki

haker moţe tako da preusmeri korisnika na neki fajl na nekom drugom server I onda se takav fajl

moţe smatrati zlonamernim I tako moţe da se promene globalne promenljive ili sabmituje

forma a na nekoj drugoj adresi da se sačuvaju podaci o korisniku, na primer.

Kako izbeći $_SERVER["PHP_SELF"] zloupotrebu?

$_SERVER["PHP_SELF"] zloupotreba moţe da se spreči korišćenejm funkcije

htmlspecialchars().

Kod za formu trebalo bi onda da izgleda ovako:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Funkcija htmlspecialchars() konvertuje specijalne karaktere u HTML entitete. Sada ako korisnik

hoće da zloupotrebi PHP_SELF promenljivu, to će rezultirati sledećim izlazom:

<form method="post" action="test_form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">

Pokušaj zloupotrebe je propao I nikakva šteta nije napravljena!

HTML Entiteti

Reserved characters in HTML must be replaced with character entities.

Characters, not present on your keyboard, can also be replaced by entities.

HTML Entities

Some characters are reserved in HTML.

If you use the less than (<) or greater than (>) signs in your text, the browser might mix them

with tags.

Simboli.php

<!DOCTYPE html>

Page 5: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

<html>

<body>

<p>I will display &euro;</p>

<p>I will display &#8364;</p>

<p>I will display &#x20AC;</p>

<p>I will display &#8704;</p>

<p>I will display &forall;</p>

<p>I will display &exist;</p>

<p>I will display &nbsp; sdfghjkl&nbsp;pčć &lt;šćĎ&nbsp;&nbsp;fdgz&#60;uiopš</p>

</body>

</html>

Provera forme PHP

Prva stvar je da sve promenljive propustimo kroz PHP-ovu htmlspecialchars() funkciju.

testformaspec.php

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

Ime: <input type="text" name="ime" >

<input type="submit" name="submit" value="to je sve">

</form>

<?php

echo "<h2>Vaš unos:</h2>";

$ime=$_POST["ime"];

echo $ime;

Page 6: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

echo "<br>";

?>

Kada se koristi funkcija htmlspecialchars() ; onda ako korisnik pokuša da sabmituje sledeći tekst

unet u tekstualno polje:

<script>location.href('http://www.matkos.in.rs')</script>

- ovo neće biti izvršeno, zato što će biti snimljeno kao HTML escaped code, kao ovo:

&lt;script&gt;location.href('http://www.matkos.in.rs')&lt;/script&gt;

Kako radi htmlspecialchars()

Spec.php

<?php

$str = "Ovo je neki <b>boldovan</b> text.";

echo htmlspecialchars($str);

?>

Kako radi location

Preusmeravam.php

<!DOCTYPE html>

<html>

<head>

<script>

function newDoc() {

location.assign("http://www.matkos.in.rs")

}

</script>

</head>

Page 7: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

<body>

<input type="button" value="predji na matkos" onclick="newDoc()">

</body>

</html>

Ovakav script je sada spreman da bude prikazan na nekoj stranici ili unutar nekog e-mail.

Mi moţemo da uradimo još dve stvari kada korisnik sabmituje formu:

1. Uklanja nepotrebne karaktere poput (višak praznina, tab, nov red) iz korisničkog unosa (sa funkcijom trim())

2. Uklanja (\) iz podataka koje unosi korisnik (pomodu PHP funkcije stripslashes() )

Sledeći korak je da napravimo funkciju koja će da sve to čekira za nasThe next step is to create a

function that will do all the checking for us (što je bolje nego da taj isti kod pišemo kod svakog

unetog polja).

Neka se ta funkcija zove test_input().

Sada moţemo da propustimo svaku unetu $_POST promenljivu kroz funkciju test_input() I to

ovako izgleda:

<?php

// definiše promenljive I dodeljuje im prazne vrednosti

$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {

$ime = test_input($_POST["ime"]);

$email = test_input($_POST["email"]);

$website = test_input($_POST["website"]);

$comment = test_input($_POST["comment"]);

$pol = test_input($_POST["pol"]);

}

function test_input($data) {

$data = trim($data);

$data = stripslashes($data);

$data = htmlspecialchars($data);

Page 8: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

return $data;

}

?>

Kako radi stripslashes($data)

Strip.php

<!DOCTYPE html>

<html>

<body>

<?php

echo stripslashes("Jel\' svanulo?");

?>

</body>

</html>

Kako radi funkcija preg_match()

Funkcija preg_match() traži zadati string u nekom drugom stringu I ako ga nađe daje true a ako ga ne

nađe daje false.

Kurs19.php

<?PHP

$nekistring='Ana ne voli Milovana';

if(preg_match('/voli/',$nekistring)){

echo 'rec /voli/postoji u recenici';}

else echo'rec /voli/ ne postoji ';

?>

Kurs20.php

<?PHP

Page 9: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

function ima_spejs($string)

{

if(preg_match('/ /',$string))

return true;

else return false;

}

if(ima_spejs('sdfg hjklk')){echo 'ima spejs';}

else echo 'nema spejsa';

?>

Sledeći korak je da označimo koja su polja neophodna da se popune I da napravimo poruke za

eventualne pogrešne unose.

punaforma.php

<!DOCTYPE HTML>

<html>

<head>

<style>

.error {color: #FF0000;}

</style>

</head>

<body>

<?php

// definiše promenljive i dodeljuje im praznu vrednost

$imeErr = $emailErr = $polErr = $websiteErr = "";

Page 10: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

$ime = $email = $pol = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {

if (empty($_POST["ime"])) {

$imeErr = "Ime je neophodno";

} else {

$ime = test_input($_POST["ime"]);

// proverava da li ime sadrţi samo slova i praznine

if (!preg_match("/^[a-zA-Z ]*$/",$ime)) {

$imeErr = "Samo slova i praznine su dozvoljene ";

}

}

if (empty($_POST["email"])) {

$emailErr = "Email je neophodan";

} else {

$email = test_input($_POST["email"]);

// proverava da li e-mail adresa je dobro formulisana

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

$emailErr = "Loš email format";

}

}

if (empty($_POST["website"])) {

$website = "";

Page 11: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

} else {

$website = test_input($_POST["website"]);

// proverava da li je URL adresa sintaksno ok (ima i crtice u URL)

if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-

9+&@#\/%=~_|]/i",$website)) {

$websiteErr = "Loš URL";

}

}

if (empty($_POST["comment"])) {

$comment = "";

} else {

$comment = test_input($_POST["comment"]);

}

if (empty($_POST["pol"])) {

$polErr = "Pol je neophodan";

} else {

$pol = test_input($_POST["pol"]);

}

}

function test_input($data) {

$data = trim($data);

$data = stripslashes($data);

Page 12: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

$data = htmlspecialchars($data);

return $data;

}

?>

<h2>PHP puna Forma sa svim proverama </h2>

<p><span class="error">* neophodna polja.</span></p>

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Ime: <input type="text" name="ime" value="<?php echo $ime;?>">

<span class="error">* <?php echo $imeErr;?></span>

<br><br>

E-mail: <input type="text" name="email" value="<?php echo $email;?>">

<span class="error">* <?php echo $emailErr;?></span>

<br><br>

Website: <input type="text" name="website" value="<?php echo $website;?>">

<span class="error"><?php echo $websiteErr;?></span>

<br><br>

Komentar: <textarea name="comment" rows="5" cols="40"><?php echo

$comment;?></textarea>

<br><br>

Pol:

<input type="radio" name="pol" <?php if (isset($pol) && $pol=="ţenski") echo "checked";?>

value="ţenski">Ţenski

<input type="radio" name="pol" <?php if (isset($pol) && $pol=="muški") echo "checked";?>

value="muški">Muški

<span class="error">* <?php echo $polErr;?></span>

Page 13: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

<br><br>

<input type="submit" name="submit" value="to je sve">

</form>

<?php

echo "<h2>Vaš unos:</h2>";

echo $ime;

echo "<br>";

echo $email;

echo "<br>";

echo $website;

echo "<br>";

echo $comment;

echo "<br>";

echo $pol;

?>

</body>

</html>

SQL Injection

SQL Injection moţe da uništi vašu bazu podataka.

SQL na Web stranicama

Page 14: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Kada se SQL koristi za prikaz podataka na nekoj web stranici, uobičajeno je da se dopusti web

korisnicima unos njihovih pretraţivačkih vrednosti- da oni mogu da pretraţuju podatke u bazi.

Kada je SQL naredba samo tekstualna, lako je, samo sa malim parčetom kompjuterskog koda

,dinamički promeniti SQL naredbe I time obezbediti korisniku da izabere podatke koje traţi:

Server Code

txtUserId = getRequestString("UserId");

txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

U ovom primeru, pravi se jedna select naredba kojom se dodaje promenljiva (txtUserId) select

stringu. Promenljiva je uzeta iz korisničkog unosa (Request) sa odgovarajuće web stranice za

unos.

SQL Injection

SQL injection je tehnika kojom zlonamerni korisnici mogu da ubace SQL komande u neku SQL

naredbu, preko stranice za inputa.

Injected SQL komande mogu da izmene SQL naredbu I tako kompromituju sigurnost web

aplikacije.

SQL Injection zasnovan na 1=1 je uvek True

Recimo da je originalni cilj koda bio da se napravi jedna SQL naredba kojom će da se selektuje

korisnik koji ima uneti korisnički id.

Ukoliko nema ničeg da spreči unos "pogrešnog" inputa, korisnik moţe da unese neki "lukavi"

input kao ovaj:

UserId:

105 or 1=1

Server rezultat

SELECT * FROM Users WHERE UserId = 105 or 1=1

Upit SQL je ok. I vratiće sve redove tabele Users, dokle god je WHERE 1=1 koje je uvek true.

Da li ovaj primer izgleda opasno? Šta ako tabela Users sadrţi imena I šifre?

Upit SQL odozgo je više nego isti kao ovaj:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1

Page 15: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Lukavi haker moţe da pristupi svim korisničkim imenima I šiframa u bazi podataka jednostavno

upisujući 105 or 1=1 u input polje.

SQL Injection bazirana na ""="" je uvek True

Evo jedne uobičajene konstrukcije, koja se koristi za verifikaciju korisnika, tj. Za logovanje na

web sajt:

User Name:

Password:

Server Code

uName = getRequestString("UserName");

uPass = getRequestString("UserPass");

sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"

Neki lukavi haker moţe da pristupi korisničkim imenima I šiframa u bazi podataka jednostavnim

unosom " or ""=" u text box za user name ili password.

Kod koji se kreira na server je ispravna SQL naredba poput ove:

Rezultat

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

SQL Injection zasnovan na doziranim SQL naredbama

Mnoge baze podataka podrţavaju dozirane SQL naredbe, odvojene tačka- zarezom.

Example

SELECT * FROM Users; DROP TABLE Suppliers

Ovaj kod SQL vratiće sve redove Users tabelu, I onda će da obriše tabelu koja se zove

Suppliers.

Page 16: PHP 5 Forma ispravnost I proveramatkos.in.rs/kurs/stvari/VII lekcija.pdf · 2016-07-25 · VII lekcija Zaštita postojećeg sistema različitim napadima na sistem, XSS, Sql injection

Ako smo imali sledeći server kod:

Server kod

txtUserId = getRequestString("UserId");

txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

I sledeći input:

User id:

105; DROP TA

Kod na server će kreirati validnu SQL naredbu kao ovu:

Rezultat

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers

Parametri za zaštitu

Neki programeri koriste "crnu listu" reči ili karaktera za pretragu u svakom SQL inputu, da bi

tako sprečili SQL injection napade.

Ovo I nije baš dobra ideja. Mnoge od ovih reči (kao delete ili drop) I karakteri (kao tačka-zarez I

znaci navoda), se koriste u svakodnevnom govoru, I trebalo bi da budu dozvoljeni u mnogim

tipovima unosa.

Jedini dokazan način za zaštitu jednog web sajta od SQL injection napada, je korišćenje SQL

parametara.

SQL parametri imaju vrednost koja se dodaje na neki SQL upit u vreme izvršavanja, na

kontrolisani način.

Ubaciti u naredbe pisane u PHP-u:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)

VALUES (:nam, :add, :cit)");

$stmt->bindParam(':nam', $txtNam);

$stmt->bindParam(':add', $txtAdd);

$stmt->bindParam(':cit', $txtCit);

$stmt->execute();