SQL injection basics come down to one idea: if user input gets concatenated directly into a SQL query as text, an attacker can supply input that changes what the query does. It has been on the OWASP Top 10 in some form for over two decades, it is still routinely found in production code during audits, and the underlying mistake — trusting a string instead of parameterizing a query — takes about five minutes to understand and about five minutes to fix once you know what to look for.
What Is SQL Injection, Really?
A web application typically takes some input (a username, a search term, a product ID from a URL) and uses it to build a database query. If that query is built by string concatenation, the database cannot tell the difference between the data the developer intended and extra SQL syntax an attacker slipped in through the same field. The database just sees text and executes whatever the final string says.
Here's a classic example of SQL injection. Imagine a login check built like this:
query = "SELECT * FROM users WHERE username = '" + input + "' AND password = '" + password + "'"
If an attacker types ' OR '1'='1 into the username field, the resulting sql injection string turns the query into:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
Because '1'='1' is always true, the query can return a row — potentially logging the attacker in as the first user in the table — without knowing any valid password.
How Do Attackers Actually Do a SQL Injection Attack?
In practice, an attacker probes a field with a single quote first to see if it breaks the page (a classic sign the input reaches the query unescaped). From there, common techniques include:
- Boolean-based injection — using
AND 1=1vs.AND 1=2to observe different responses and infer data one bit at a time. - Union-based injection — appending
UNION SELECTstatements to pull data from other tables into the visible output. - Error-based injection — deliberately triggering database errors that leak schema information in the response.
- Time-based blind injection — using functions like
SLEEP()to infer true/false conditions when no error or data is visible, purely from response timing.
None of these require exotic tools. Manual testing with a browser and a proxy, or automated tools that fuzz every parameter, will find an unprotected endpoint fairly quickly, which is exactly why this class of bug shows up so often in breach postmortems.
How to Prevent SQL Injection
The fix that actually works, every time, is parameterized queries (also called prepared statements). Instead of building a string, you pass the query structure and the user input separately, and the database driver keeps them separate:
db.execute("SELECT * FROM users WHERE username = ? AND password = ?", [input, password])
With this pattern, ' OR '1'='1 is treated as a literal string to search for, not as SQL syntax, no matter what characters it contains. Every mainstream language and ORM supports parameterized queries or an equivalent — there is rarely a good reason to build a raw query from concatenated input.
A layered defense adds:
- Input validation — reject unexpected characters or formats for fields with a known shape (numeric IDs, email addresses).
- Least-privilege database accounts — the application's database user should not have permissions it does not need, limiting blast radius if a query is ever manipulated.
- A web application firewall (WAF) — a WAF for SQL injection acts as a second layer that can catch known attack patterns at the network edge, but it is not a substitute for parameterized queries; WAFs can be bypassed with encoding tricks and should never be your only control.
- Static analysis — SAST tooling can flag string-concatenated queries during code review, before the code ever reaches production.
FAQ
What is an example of SQL injection in a real query?
The classic example is a login form where the query is built with string concatenation. Supplying ' OR '1'='1' -- as the username causes the query to always evaluate true, potentially bypassing authentication entirely.
Can a WAF alone stop SQL injection?
No. A WAF for SQL injection helps block known attack signatures at the perimeter, but attackers routinely bypass WAFs with encoding and obfuscation. Parameterized queries fix the underlying flaw and should always be the primary control.
Is SQL injection still a real risk in 2024?
Yes. It remains common in legacy codebases, hastily written internal tools, and ORMs used incorrectly (raw query builders that accept string input). It shows up regularly in vulnerability disclosures and bug bounty reports.
Does using an ORM automatically prevent SQL injection?
Mostly, but not automatically. Standard ORM query builders parameterize by default, but most ORMs also offer an escape hatch for raw SQL, and injection bugs reappear whenever developers use that escape hatch with unsanitized input.