OWASP A03: Injection
SQL Injection: Kako jedna loša linija koda može srušiti firmu
2026-07-12 · Shieldome Scout
SQL Injection je godinama bio broj jedan na OWASP listi i nije slučajno: napadaču daje direktan pristup vašoj bazi podataka. Objašnjavamo kako funkcioniše i kako se zaštititi.
← Blog
Šta je SQL Injection?
SQL Injection (SQLi) se dešava kada napadač ubaci SQL kod u polje za unos koje aplikacija prosleđuje direktno bazi podataka. Umesto da se unos tretira kao podatak, baza ga izvršava kao komandu. Rezultat: napadač može da čita, menja ili briše podatke, zaobiđe logovanje, pa čak i preuzme kontrolu nad serverom.
Evo klasičnog primera ranjivog PHP koda:
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
Ako korisnik upiše ' OR '1'='1 kao korisničko ime, upit postaje:
SELECT * FROM users WHERE username = '' OR '1'='1'
Uslov '1'='1' je uvek tačan, pa upit vraća sve korisnike — i napadač se loguje bez lozinke.
Vrste SQL Injection napada
In-band SQLi (klasični)
Napadač vidi rezultat direktno u odgovoru aplikacije. Najčešći tip, uključuje Error-based (podaci se izvlače kroz error poruke) i Union-based (korist UNION SQL operatora za kombinovanje podataka iz više tabela).
Blind SQLi
Aplikacija ne prikazuje greške niti podatke direktno, ali menja ponašanje na osnovu upita. Boolean-based: odgovor se razlikuje za tačan i netačan uslov. Time-based: napadač koristi SLEEP() funkciju da izmeri da li je uslov tačan po kašnjenju odgovora.
Out-of-band SQLi
Podaci se izvlače kroz drugi kanal (DNS zahtevi, HTTP pozivi). Ređi, ali moćan kada su drugi metodi blokirani.
Realne posledice
SQLi napadi su odgovorni za neke od najvećih povreda podataka u istoriji interneta:
- Heartland Payment Systems (2008): 130 miliona kreditnih kartica ukradeno
- TalkTalk (2015): 157.000 korisnika, kazna od 400.000 funti
- Equifax (2017): delom kroz SQLi, 147 miliona osoba
Posledice za malu ili srednju firmu: curenje baze korisnika, gubitak poverenja, GDPR kazne do 4% globalnog prihoda, tužbe i potencijalni krivičnopravni odgovor vlasnika.
SQLi je čest jer su simptomi nevidljivi: ranjiva aplikacija radi normalno sve dok napadač ne odluči da udari. Pasivna detekcija — analiza error poruka, HTTP odgovora i ponašanja forme — može otkriti ranjivost pre nego što napadač to uradi.
Kako se odbraniti
1. Parametrizovani upiti (Prepared Statements)
Jedini siguran način da sprečite SQLi: odvojiite SQL strukturu od korisničkih podataka.
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$result = $stmt->fetchAll();
Baza ovde tretira $username isključivo kao podatak, bez obzira na sadržaj.
2. ORM biblioteke
Django ORM, Hibernate, ActiveRecord, SQLAlchemy — moderne ORM biblioteke koriste parametrizovane upite automatski. Direktno pisanje SQL stringa unutar ORM-a i dalje može biti ranjivo.
3. Validacija i sanitizacija unosa
Whitelist validacija (dozvolite samo očekivane formate), ograničite dužinu, tipove i znakove. Ovo je dopunska zaštita, nikad jedina.
4. Princip najmanje privilegija
Nalog baze podataka koji koristi aplikacija ne sme imati DROP, CREATE, niti pristup sistemskim tabelama. Čak i ako dođe do SQLi-ja, napadač ima ograničene mogućnosti.
5. WAF (Web Application Firewall)
WAF može blokirati poznate SQLi pattern-e, ali nije zamena za siguran kod — napadači rutinski zaobilaze WAF-ove obfuscation tehnkama.
6. Redovni vulnerability assessment
Automatizovana detekcija SQLi indikatora (error poruke, aberantna ponašanja) kao deo redovne procene — pre nego što to uradi napadač.
Proverite bezbednost vašeg sajta
Profesionalna procena ranjivosti. OWASP Top 10, dark web monitoring, PDF izveštaj za 2–3 radna dana.
Zatražite procenu →
← Blog
What Is SQL Injection?
SQL Injection (SQLi) occurs when an attacker inserts SQL code into an input field that the application passes directly to the database. Instead of treating the input as data, the database executes it as a command. The result: the attacker can read, modify, or delete data, bypass login, and even take control of the server.
Here is a classic example of vulnerable PHP code:
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
If a user enters ' OR '1'='1 as the username, the query becomes:
SELECT * FROM users WHERE username = '' OR '1'='1'
The condition '1'='1' is always true, so the query returns all users — and the attacker logs in without a password.
Types of SQL Injection Attacks
In-band SQLi (Classic)
The attacker sees the result directly in the application response. The most common type, including Error-based (data is extracted through error messages) and Union-based (uses the UNION SQL operator to combine data from multiple tables).
Blind SQLi
The application does not display errors or data directly, but changes behavior based on the query. Boolean-based: the response differs for true and false conditions. Time-based: the attacker uses the SLEEP() function to measure whether a condition is true based on response delay.
Out-of-band SQLi
Data is extracted through another channel (DNS requests, HTTP calls). Rarer, but powerful when other methods are blocked.
Real-World Consequences
SQLi attacks are responsible for some of the largest data breaches in internet history:
- Heartland Payment Systems (2008): 130 million credit cards stolen
- TalkTalk (2015): 157,000 users affected, £400,000 fine
- Equifax (2017): partly through SQLi, 147 million people affected
Consequences for a small or medium business: user database leak, loss of trust, GDPR fines up to 4% of global revenue, lawsuits, and potential criminal liability for owners.
SQLi is common because the symptoms are invisible: a vulnerable application works normally until an attacker decides to strike. Passive detection — analyzing error messages, HTTP responses, and form behavior — can reveal vulnerabilities before an attacker does.
How to Defend Against SQLi
1. Parameterized Queries (Prepared Statements)
The only safe way to prevent SQLi: separate SQL structure from user data.
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$result = $stmt->fetchAll();
The database treats $username exclusively as data, regardless of content.
2. ORM Libraries
Django ORM, Hibernate, ActiveRecord, SQLAlchemy — modern ORM libraries use parameterized queries automatically. Directly writing SQL strings within an ORM can still be vulnerable.
3. Input Validation and Sanitization
Whitelist validation (allow only expected formats), limit length, types, and characters. This is supplementary protection, never the only defense.
4. Principle of Least Privilege
The database account used by the application must not have DROP, CREATE, or access to system tables. Even if SQLi occurs, the attacker has limited capabilities.
5. WAF (Web Application Firewall)
A WAF can block known SQLi patterns, but it is not a substitute for secure code — attackers routinely bypass WAFs using obfuscation techniques.
6. Regular Vulnerability Assessment
Automated detection of SQLi indicators (error messages, aberrant behaviors) as part of regular assessment — before an attacker does it for you.
Check Your Website Security
Professional vulnerability assessment. OWASP Top 10, dark web monitoring, PDF report in 2–3 business days.
Request Assessment →