Zaštita od SQLi pomoću PDO klase


SQL injection je proces ubacivanja posebnog (zlonamernog) koda u bazu podataka, koji hakerima omogućuje pristup administatorskom delu sajta, ili upravljanje odnosno krađu korisničkih podataka.

PDO je skraćenica od PHP Data Objects i predstavlja PHP biblioteku specijalno kreiranu radi sigurnije interakcije sa bazama podataka. PDO je potpuno objektno orijentisana, i ne može se koristiti kroz proceduralno programiranje.

1. Primer konekcije na bazu podataka


try 
{
    $db = new PDO('mysql:host=localhost;dbname=db_name&charset=utf8', 'username', 'password', 
          array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
} 
catch (PDOException $e) 
{
    // Greska pri konekciji na bazu podataka
}

 

Standardni SQL upiti i prikaz rezultata

Sada, kada smo konektovai nabazu podataka, možemo izvršiti upita nad tabelom:


$query = $db->query('SELECT name FROM users');
$fetch = $query->fetchAll();
 
// Prvi rezultat
echo $fetch[0]['name'];
 
// Svi rezultati
foreach ($fetch as $user) 
{
	echo $user['name'];
}

// Broj redova u tabeli
echo $query->rowCount();

 

Pripremljeni upiti (Prepared statements)

Kada god vršite interakciju sa bazom podataka, preporučuje se da to radite pomoću pripremljenih upita. Radi se o tome da se najpre bazi podataka pošalje pripremljen upit, a tek kasnije se taj upit dopuni sa unosom korisnika, tako da baza "zna" kakve podatke da očekuje od korinsika. 

2. Primeri pripremljenih upita:


// Klasičan način
$query = $db->prepare('SELECT id FROM users WHERE username = :username AND password = :password');
 
$array = array
(
	'username' => 'darko',
	'password' => 'darpet85'
);
 
$query->execute($array);

// Brži način
$query = $db->prepare('SELECT id FROM users WHERE username = ? AND password = ?');
 
$array = array('darko', 'darpet85');
$query->execute($array);

Kao što se vidi u primeru, drugi način je znatno jednostavniji za rad, ali treba biti oprezan ako se radi o većem SQL upitu, jer mnoštvo ? može da izazove konfuziju. 

3. Primer INSERT upita


$query = $db->prepare('INSERT INTO users (username, name, password) VALUES (?, ?, ?)');
 
# A possibly problematic query!
$array = array('carrot', "John O'Dear", 'password');
 
$query->execute($array);

 

Dodatna zaštita postavljanjem tipova podataka

PDO omogućava da najpre postavimo očekivani tip podatka pre nego ga pošaljemo unutar pripremljenog upita. 


$query = $db->prepare('INSERT INTO users(username, password, age) VALUES (:username, :password, :age)');
 
// Ako ne navedemo tip podrazumevano je PDO::PARAM_STRING
$query->bindParam(':username', 'darko');
$query->bindParam(':name', 'darpet85');
$query->bindParam(':age', 28, PDO::PARAM_INT);
 
# Execute the query
$query->execute();

// brži način:
$query = $db->prepare('INSERT INTO people (username, password, age) VALUES (?, ?, ?)');
 
$query->bindParam(1, 'darko');
$query->bindParam(2, 'darpet85');
$query->bindParam(3, 28, PDO::PARAM_INT);
 
$query->execute();

Korišćenjem PDO biblioteke kao što je gore prikazano, gotovo da ste se potpuno obezbedili od SQL injection-a. 




Ostavite komentar





Komentari posetilaca


  • Marco | 08.04.2014 16:14

    Super objasnjeno, hvala!