Injection
Lectură estimată: 3 minute
Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.
Injection (SQL, comenzi de sistem, LDAP) apare când amesteci date venite de la utilizator cu cod sau interogări interpretate. Atacatorul își strecoară propriul cod în locul unei valori. E printre cele mai vechi și mai periculoase categorii — și printre cele mai ușor de prevenit.
SQL injection — cum apare
// VULNERABIL: valoarea utilizatorului devine parte din interogare
$email = $_GET["email"];
$sql = "SELECT * FROM users WHERE email = '$email'";
// dacă email = ' OR '1'='1 -> returnează toți utilizatorii
// dacă email = '; DROP TABLE users; -- -> dezastruSoluția: interogări parametrizate
// CORECT: valoarea e trimisă separat, niciodată interpretată ca SQL
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
// Laravel / Eloquent fac asta automat:
User::where("email", $email)->first();
DB::select("SELECT * FROM users WHERE email = ?", [$email]);Unde mai apare injection
- Comenzi de sistem: `shell_exec("convert $fisier ...")` cu `$fisier` de la utilizator.
- Nume de coloane/tabele dinamice (nu se pot parametriza — folosește o listă albă).
- `ORDER BY $coloana` — validează `$coloana` dintr-o listă permisă.
- Query-uri raw construite prin concatenare, chiar și în ORM.
Reguli
- Nu construi NICIODATĂ SQL prin concatenare cu input de utilizator.
- Parametri / prepared statements / ORM — mereu.
- Pentru părți care nu se pot parametriza (nume de coloane), listă albă strictă.
- Pentru comenzi de sistem, evită-le; dacă trebuie, folosește funcții cu argumente separate (nu shell), și validează strict.
„Sanitizarea" nu e soluția
Încercarea de a „curăța" input-ul cu `str_replace`, escape manual sau expresii regulate e fragilă — mereu există un caz pe care l-ai ratat. Parametrizarea rezolvă problema la rădăcină: datele nu ajung niciodată să fie interpretate ca cod.
Sortare dinamică sigură
$permise = ["nume", "data", "pret"]; $sort = in_array($request->get("sort"), $permise, true) ? $request->get("sort") : "data"; $produse = Produs::orderBy($sort, "desc")->get(); // $sort nu poate fi decât una din 3 valori — injection imposibil
Exercițiu
Ia o interogare care folosește concatenare (sau scrie una vulnerabilă intenționat, local). Demonstrează-ți injection-ul cu un input de tip `' OR '1'='1`. Apoi rescrie-o cu prepared statement / ORM și verifică că același input nu mai face nimic.
Greșeli frecvente
- Construiești SQL cu variabile în string.
- „Sanitizezi" manual în loc să parametrizezi.
- `ORDER BY` sau `LIKE` cu input direct.
- Rulezi comenzi de sistem cu argumente de la utilizator prin shell.
De reținut
- Injection = date de utilizator interpretate ca cod/interogare.
- Prepared statements / ORM / parametri — mereu, fără excepție.
- Ce nu se poate parametriza (nume de coloane) → listă albă.
- Sanitizarea manuală e fragilă; parametrizarea rezolvă la rădăcină.
Pe scurt
Nu amesteca niciodată date de utilizator cu cod. Parametri și ORM elimină SQL injection; liste albe pentru părțile dinamice care rămân.
SQL injection prevenită prin separarea valorilor
Parametrizarea este controlul de bază pentru valorile SQL. Validarea poate limita domeniul, dar nu înlocuiește parametrii. Pentru identificatori precum coloana de sortare, folosește o allowlist; aceștia nu sunt valori obișnuite de parametru. Exemplele de securitate se rulează numai într-un laborator propriu, fără a testa site-uri străine. Escaparea HTML nu protejează interogările SQL.
Exemplu de lucru
Laravel:
$email = $request->validate(['email' => ['required', 'email']])['email'];
$user = User::where('email', $email)->first();
Sortare: mapare newest→created_at desc, oldest→created_at asc.
De evitat: concatenarea unei valori în DB::select cu SQL construit manual.
Test: intrare cu ghilimele rămâne dată, fără schimbarea structurii.Interpretarea rezultatului
Query builderul parametrizat nu autorizează accesul la toate rândurile. Aplică și scope-ul utilizatorului unde este necesar. Pentru SQL raw, verifică bindingurile concrete și nu presupune că orice metodă cu „raw” este sigură. Nu publica payloaduri împotriva unui serviciu fără autorizare.
Exercițiu de consolidare
Construiește un test local pentru o valoare cu apostrof și confirmă că nu provoacă eroare sau extinderea rezultatului.
Aplicație practică
Sarcina
Verifică folosirea parametrilor într-o interogare locală.
Rezolvare orientativă și verificare
Testează o valoare cu ghilimele pe date fictive și confirmă că este tratată ca text.
Greșeală de evitat
Nu testa injection pe site-uri fără autorizare.
Documentație și surse
- OWASP Top 10 — OWASP
- Learn web development — MDN
Ți-a plăcut lecția? Continuă cursul complet
Ai citit o lecție gratuită. Celelalte lecții, aplicațiile practice și materialele se deblochează odată cu cursul.
149 lei
Plată unică, acces pe viață la toate cele 6 lecții.
Vezi ce conține cursul →