SQL injection has topped vulnerability lists for over two decades, and it still causes breaches today. The mechanism is simple, the damage can be catastrophic, and — encouragingly — the fix is well understood and easy to apply. This guide explains how the attack works and the single practice that defeats it.
How the attack works
The vulnerability arises when an application builds a SQL query by gluing user input directly into the query string. If a login form inserts the username straight into the SQL, an attacker can type input that closes the intended query and adds their own — bypassing the password check, dumping the database, or deleting tables. The database cannot tell the difference between your query and the attacker’s injected code, because to it, it is all one string.
Why concatenation is the root cause
The core mistake is mixing code and data. When you concatenate input into a query, you let the user influence the structure of the SQL, not just the values. Everything else — escaping, blacklisting dangerous words — is a patch over this fundamental flaw, and patches leak.
The fix: parameterized queries
The reliable solution is parameterized queries, also called prepared statements. You write the query with placeholders for the values, then pass the values separately. The database treats those values strictly as data, never as code, so injected SQL is harmless — it becomes just a funny-looking string to search for. Virtually every database library supports this, and using it everywhere closes the vulnerability.
Defence in depth
- Always use parameterized queries or a well-built ORM — never string concatenation.
- Apply least privilege: the app’s database user should only have the permissions it needs.
- Validate and constrain input as an additional layer, not the primary defence.
- Keep detailed errors out of responses, so attackers learn nothing from probing.
The takeaway
SQL injection persists not because it is hard to prevent but because unsafe habits linger. Treat user input as data, never as code, use parameterized queries everywhere, and this entire class of attack disappears.