Cum sa previ SQL Injection

SQL injections sunt o vulnerabilitate foarte frecventa in apicatiile de pe internet care folosesc baza de date.

Foarte multi programatori nu sunt constienti ca interogarile SQL pot fi modificate extern, si presupun ca aceste comenzi sunt sigure. Asta presupune ca orice atac SQL va trece de orice masura de control si de securitate existenta pe site, si de orice metoda de autentificare folosita. In plus multi dintre ei se gandesc : Cine va incerca sa imi Hack-uiasca site-ul ? Ce motiv ar avea sa faca asta ?

Direct SQL Command Injection este o tehnica prin care un atacator creaza sau modifica o interogare SQL existenta pentru a afla informatii confidentiale, pentru a suprascrie informatii, sau chear pentru a crea noi super useri. Asta se face prin introducerea in input-urile de pe site care sunt folosite in interogariile SQL de comenzi SQL pentru asi realiza scopul propus. Dar destul cu teoria, iata cateva exemple de SQL HAcks care din pacate sunt reale.

Stergerea datelor dintr-un tabel

Acesta este un exemplu de injection, sa consideram un formular de login pe un site care are urmatoarea interogare SQL in codul php:

mysql_query('SELECT * FROM user WHERE username = "' . $_GET['username'] . '");

Un user rau-intentionat poate introduce in input-ul user valoarea “”; DELETE FROM user WHERE 1″, care va avea ca efect stergera tuturor userilor din tabel.

SELECT * FROM user WHERE username = ""; DELETE FROM user WHERE 1 ;

Aceasta tip de SQL Injection este posibil sa fie blocat de extensia mysql a PHP-ului care nu permite mai multe interogari mysql in mod defaulst, dar acesta este un exemplu.

Resetarea unei parole / obtinerea de noi privilegii

Se luam acest query relativ siimplu de schimbarea a parolei unui user
$query = "UPDATE user SET password="'.$_GET['password'].'" WHERE id="'.$_GET['user_id'].'" ;

O persoana rau intentionata poate obtine privilegii de admin foarte simplu :
[php]
// user_id == ” or username like ‘%admin%’; —
$query = “UPDATE user SET password=’…’ WHERE id=”” or username like ‘%admin%’; –“;
[/php]

Cum Prevenim SQL injection

E posibil sa crezi ca aceste brese de securitate sunt posibile doar daca atacatorul stie structura bazei de date. Ai dreptate dar, sa nu crezi ca e greu sa afli structura, fiind numeroase cai de a o afla : mesaje de eroare sql printate pe ecran, folosirea unui script open source, si chear simpla incercare a mai multor variante fiind cunoscut faptul ca multi programatori folosesc aceleasi denumiri ( sau destul de apropiate ) pentru nume de tabele si campuri.

Iata un exemplu de atac SQL pentru a ghicii numele unui tabel :
[sql]
SELECT … FROM table WHERE id = ‘$user_id’;
SELECT … FROM table WHERE id = ” AND 1=(SELECT COUNT(*) FROM tabname); –‘;
[/sql]
Dupa cateva incercari, inlocund tabname cu diferite variante atacatorul va gasi un nume de tabel valid.

Pentru a preveni aceste atacuri primul pas este sa construiti aplicatia luand in calcul si posibilitatea unui atac. Iata si cateva metode de prevenire a atacurilor SQL:

  • Nu va conectati niciodata la baza de date SQl cu un super user. Incercati sa limitati privilegiile userului pe care il folositi la conectare la minum posibil.
  • Intodeauna verificati daca input-urile de la useri sunt ceea ce va asteptati sa fie. Folositi functiile php de validare ( ex: is_numeric() ) sau chiar si validare folosind expresii regulate ( regexp ) .
  • Transformati orice camp in tipul pe care il asteptati:
    [php]
    settype($offset, ‘integer’);
    $query = “SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;”;
    // please note %d in the format string, using %s would be meaningless
    $query = sprintf(“SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;”,
    $offset);
    [/php]
  • Limitati numarul de caractere in input-urile userilor. Desi nu va impiedica toate atacurile SQL va oprii o mica parte din ele 🙂
  • Nu printati pe ecran mersajele de eroare SQL, tineti minte ca am vorbit si mai sus de riscul ca atacatorul sa afle structura DB din aceste mesaje..
  • Si un exemplu de “Best Practice” SQL direct din manualul PHP :
    [php]
    // Quote variable to make safe
    function quote_smart($value)
    {
    // Stripslashes
    if (get_magic_quotes_gpc()) {
    $value = stripslashes($value);
    }
    // Quote if not integer
    if (!is_numeric($value)) {
    $value = “‘” . mysql_real_escape_string($value) . “‘”;
    }
    return $value;
    }// Connect
    $link = mysql_connect(‘mysql_host’, ‘mysql_user’, ‘mysql_password’)
    OR die(mysql_error());// Make a safe query
    $query = sprintf(“SELECT * FROM users WHERE user=%s AND password=%s”,
    quote_smart($_POST[‘username’]),
    quote_smart($_POST[‘password’]));
    mysql_query($query);
    [/php]

Sper ca acest articol va deschis apetitul si veti incepe sa va protejati aplicatiile web.

Share your love
Gabriel Solomon
Gabriel Solomon

Ultramaratonist, Galantom, organizator de evenimente sportive

Articles: 1218

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.