SQL Injection
SQL Injection este o tehnica de injectare de cod care exploateaza o vulnerabilitate
de securitate ce apare in stratul “baza de date” al unei aplicatii.
Vulnerabilitatea este prezenta atunci cand datele
introduse de 838h74i utilizator sunt incorect filtrate sau gresite, aceste lucruri
ducand la o executie neasteptata. Este o instanta dintr-o clasa mai generala de
vulnerabilitati care pot aparea ori de cate ori un
limbaj de programare sau de scripting este incorporat in interiorul altuia. Atacurile SQL Injection sunt totodata cunoscute ca atacuri prin
insertie SQL.
Forme ale vulnerabilitatii
1.Siruri de caractere de control filtrate incorect
Aceasta forma de
insertie SQL se produce atunci cand datele introduse de utilizator nu sunt
filtrate pentru a scapa de secventele de control si se trece direct intr-o
instructiune SQL. Acest lucru duce la manipularea potentialului
de declaratii efectuate pe baza de date de catre utilizatorul final al
aplicatiei.
Urmatoarea linie de
cod ilustreaza aceasta vulnerabilitate:
statement 'SELECT * FROM users WHERE name = '' userName
Acest cod SQL este conceput pentru a extrage inregistrari ale numelui de
utilizator specificat din tabelul users. Cu toate acestea, in cazul in care
variabila “userName” este conceputa intr-un mod
specific de catre un utilizator rau intentionat, declaratia SQL poate face
mai mult decat a intentionat autorul.
De exemplu, setarea
variabilei “userName”:
a' or 't'='t
transforma acea declaratie SQL in:
SELECT FROM users WHERE name 'a' OR 't' 't';
Daca acest cod ar
urma sa fie folosit intr-o procedura de autentificare, atunci acest exemplu ar
putea fi utilizat pentru a forta alegerea unui nume de utilizator valid,
deoarece evaluarea ‘t’=‘t’ este intotdeauna adevarata.
Urmatoarea valoare a variabilei “userName” in situatia de mai jos ar determina
stergerea tabelului “users”, precum si selectia tuturor datelor din tabelul “userinfo”
(in esenta dezvaluie informatiile despre fiecare utilizator), folosind un API
care permite mai multe declaratii:
a'; DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't;
Aceasta intrare
face declaratia finala SQL, dupa cum urmeaza:
SELECT FROM users WHERE name 'a';
DROP TABLE users;
SELECT FROM userinfo WHERE 't' 't';
In timp ce majoritatea implementarilor SQL server permit mai multe declaratii care urmeaza sa fie executate cu un apel in acest fel, unele API-uri SQL, cum ar fi PHP mysql_query () nu permit acest lucru din motive de securitate. Acest lucru previne atacatorii sa injecteze interogari complet separate, dar nu ii impiedica sa modifice interogarile. 2.Manipularea incorecta a tipurilor Aceasta forma de isertie SQL apare atunci cand un camp utilizator nu este puternic declarat (ca tip de data) sau nu este verificat pentru constrangeri de tip. Acest lucru ar putea avea loc atunci cand un camp numeric urmeaza sa fie utilizat intr-o declaratie SQL, dar programatorul nu face verificari pentru a valida ca datele introduse de utilizator sunt numerice. De exemplu:
statement 'SELECT * FROM userinfo WHERE id = ' a_variable
Este clar din aceasta declaratie ca autorul a intentionat ca “a_variable” sa fie un numar corelat la campul “id”. Cu toate acestea, in cazul in care este de fapt un sir de caractere, atunci utilizatorul poate manipula o declaratie la alegere, ocolind astfel nevoia de caractere de caractere de control. De exemplu, setarea “a_variable”:
1;DROP TABLE users
va sterge tabelul “users” din baza de date, deoarece SQL va face urmatoarele:
SELECT FROM userinfo WHERE id ;DROP TABLE users;
3.Vulnerabilitatile in interiorul server de baze de date Uneori vulnerabilitatile poate exista in cadrul serverului de baze de date in sine, cum a fost cazul cu functia MySQL mysql_real_escape_string (). Acest lucru permite unui atacator sa efectueze cu succes un atac prin insertie SQL pe baza de caractere Unicode nocive, chiar daca de intrarea utilizatorului este controlata. Acest bug a fost remediat o data cu lansarea versiunii 5.0.22 (in data de 24.05.2006).
4.Insertia SQL oarba (Blind SQL Injection) Blind SQL Injection este utilizata atunci cand o aplicatie web este vulnerabila la o insertie SQL, dar rezultatele de insertiei nu sunt vizibile pentru atacator. Pagina cu vulnerabilitatea s-ar putea sa nu fie una care afiseaza date, dar afisajul va fi diferit in functie de rezultatele declaratiei logice inserate. Acest tip de atac poate deveni intensiv in timp deoarece o noua declaratie trebuie conceputa pentru fiecare bit recuperat. Exista mai multe instrumente care pot automatiza aceste atacuri o data ce locul vulnerabil si informatiile tinta au fost stabilite. 5.Raspunsuri conditionale Un tip de injectie SQL oarba forteaza baza de date pentru a evalua o declaratie logica pe un ecran obisnuit al aplicatiei:
SELECT booktitle FROM booklist WHERE bookId 'OOk14cd' AND 1 ;
va rezulta intr-o pagina normala in timp ce:
SELECT booktitle FROM booklist WHERE bookId 'OOk14cd' AND 1 ;
probabil va da un rezultat diferit in cazul in care pagina este vulnerabila la o insertie SQL. O insertie ca aceasta ar sugera atacatorului ca o insertie SQL oarba este posibila, lasand atacatorul sa elaboreze declaratii care se evalueaza true sau false in functie de continutul altei coloane sau tabel din afara coloanei/coloanelor din declaratia SELECT. 6.Erori conditionale Acest tip de insertie SQL oarba cauzeaza o eroare SQL prin fortarea bazei de date sa a evalueze o declaratie care cauzeaza eroare in cazul in care declaratia WHERE este adevarata. De exemplu, :
SELECT 0 FROM users WHERE username 'Ralph';
doar impartirea la zero va fi evaluata si poate conduce la o eroare in cazul in care utilizatorul Ralph exista. 7.Intarzieri Intarzierile sunt un tip de insertie SQL oarba care provoaca motorul SQL sa execute o interogare de lunga durata sau o intirziere de timp, in functie de logica inserata. Atacatorul poate masura apoi timpul necesar pentru incarcarea paginii pentru a determina daca declaratia inserata este adevarata. Prevenirea SQL injection Pentru a se proteja de insertia SQL, datele introduse de utilizator nu trebuie sa fie direct incorporate in declaratiile SQL. Declaratiile parametrizate sunt de preferat a fi utilizate, sau intrarea unui utilizator trebuie sa fie atent filtrata sau curatata de secventele de control. 1.Declaratiile parametrizate O data cu dezvoltarea de platforme, declaratiile parametrizate pot fi folosite deoarece functioneaza cu parametri in locul includerii datelor introduse de utilizator in declaratie. In multe cazuri, declaratia SQL este fixa, si fiecare parametru este un scalar, nu un tabel. Intrarea unui utilizator este apoi alocata unui parametru. Acesta este un exemplu folosind Java si JDBC API:
PreparedStatement prep conn.prepareStatement 'SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?'
prep.setString 1, username
prep.setString 2, password
prep.executeQuery
Similar, in C#:
using SqlCommand myCommand new SqlCommand 'SELECT * FROM USERS WHERE USERNAME=@username AND PASSWORD=HASHBYTES('SHA1',
@password)', myConnection))
In versiunea PHP 5 si mai nou, exista mai multe optiuni pentru utilizarea declaratiilor parametrizate. Stratul PDO al bazei de date este una dintre ele:
$db new PDO 'pgsql:dbname=database'
$stmt $db->prepare 'SELECT priv FROM testUsers WHERE username=:username AND password=:password'
$stmt->bindParam ':username' $user
$stmt->bindParam ':password' $pass
$stmt->execute
Exista, de asemenea metode sfecifice ale producatorului; de exemplu, utilizand mysqli, prelungire pentru MySQL 4.1 si mai nou, pentru a crea declaratii parametrizate:
$db new mysqli 'localhost' 'user' 'pass' 'database'
$stmt $db -> prepare 'SELECT priv FROM testUsers WHERE username=? AND password=?'
$stmt -> bind_param 'ss' $user $pass
$stmt -> execute
2.Aplicarea la nivelul bazei de date In prezent, numai H2 Database Engine are capacitatea de a pune in aplicare interogari parametrizate. Cu toate acestea, un dezavantaj este acela ca interogarea de exemplu nu poate fi posibila sau practica, deoarece este dificil sa se implementeze interogare folosind interogari parametrizate. 3.Punere in aplicare la nivel de codare Folosind librarii relationale obiect se evita necesitatea de a scrie cod SQL. Biblioteca ORM va genera declaratii SQL parametrizate de la codul orientat obiect. 4.Curatarea Un pas inainte, desi predispus la erori, o modalitate de a preveni preparate injectabile este de a scapa de caracterele care au o semnificatie speciala in SQL. Manualul pentru SGBD SQL explica ce caractere care au o semnificatie speciala, lucru ce permite crearea unei liste negre de caractere ce au nevoie de traducere. De exemplu, fiecare aparitie a unei ghilimele simple intr-un parametru trebuie inlocuita de doua ghilimele simple pentru a forma un sir valid SQL. In PHP, de exemplu, se obisnuieste pentru a curata parametri functia
mysql_real_escape_string inainte de a trimite interogarea SQL:
$query sprintf 'SELECT * FROM Users where UserName='%s' and Password='%s
mysql_real_escape_string $Username
mysql_real_escape_string $Password
mysql_query $query
Acest lucru este predispus la eroare, pentru ca este usor de uitat sa se curete un sir dat. Exemple reale - SQL Injection 1.In data de 1 noiembrie 2005, un elev de liceu a folosit o insertie SQL pentru a patrunde in site-ul unei reviste de securitate taiwaneze si a fura informatiile clientilor. 2.In data de 13 ianuare 2006, un grup de infractori rusi au patruns intr-un site al guvernului Rhode Island, si se presupune ca a furat datele cartilor de credit de la persoane care au facut afaceri online cu agentiile de stat. 3.In 2 martie 2007, Sebastian Bauer a descoperit un defect de insertie SQL in pagina de login knorr.de. 4.La data de 29 iunie 2007, un infractor a neutralizat site-ul Microsoft din Marea Britanie folosind SQL Injection. Un purtator de cuvant al Microsoft a recunoscut problema site-ului The Register din U.K. 5.In ianuarie 2008, zeci de mii de PC-uri au fost infectate de un atac SQL Injection automat, care a exploatat o vulnerabilitate in codul aplicatiilor ce utilizeaza Microsoft SQL Server pentru stocarea bazei de date. 6.La data de 17 august 2009, Departamentul de Justitie al Statelor Unite au acuzat un cetatean american, Albert Gonzalez si doi rusi anonimi de furtul a 130 milioane de numere de carti de credit folosind un atac SQL Injection. In relatarile presei apare ca “cel mai mare caz de furt de identitate din istoria Statelor Unite”, omul a furat carduri de la un numar de victime corporative dupa cercetarea sistemelor de prelucrare a platii. Printre companiile lovite se numara: procesorul de sisteme de plata Heartland Payment Systems, lantul de magazine economice 7-Eleven, si lantul de supermarketuri Hannaford Brothers. 7.In decembrie 2009, un atacator a patruns intr-o baza de date RockYou! care continea in format text numele de utilizator si parole necriptate pentru aproximativ 32 milioane de utilizatori, prin utilizarea unui atac SQL Injection.