SQL injection is not dead
Despite 25 years of awareness, SQL injection remains in the top 3 most exploited vulnerabilities. ORMs have reduced the attack surface but haven't eliminated the problem. Every time a developer writes a raw query, concatenates user input into SQL, or uses an ORM in unsafe mode, the risk comes back.
How it works
The attacker inserts SQL into a field that will be incorporated into a server-side query. If the value isn't parameterized, the SQL engine interprets it as code.
Basic example: the login form executes SELECT * FROM users WHERE email = '[input]' AND password = '[input]'. The attacker enters admin'-- as the email. The query becomes SELECT * FROM users WHERE email = 'admin'--' AND password = ''. The SQL comment -- skips the password check.
The variants
Union-based
The attacker uses UNION SELECT to extract data from other tables. If the original query returns 3 columns, the attacker injects ' UNION SELECT username, password, email FROM users-- to retrieve every user's credentials.
Blind (boolean)
When the application doesn't return results directly, the attacker asks yes/no questions. ' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1)='a'-- tests whether the first character of the password is a. Automated, this extracts the database character by character.
Time-based
Same principle as blind, but based on response time. ' AND IF(1=1, SLEEP(5), 0)-- causes a 5-second delay if the condition is true. Slower but works even when responses are identical.
Second-order
The injection isn't exploited immediately. The malicious value is stored (e.g., in a user profile), then used later in another unparameterized query. Harder to detect because input and output are separated.
What ORMs don't protect
DB::raw() in Laravel: any raw expression reintroduces the risk.extra() in Django: injections in additional WHERE clauses$where in MongoDB: server-side JavaScript evaluationORDER BY clauses: often built by concatenation even in ORMsModern defenses
? or $1). Never concatenate.DROP, no FILE, no access to system tables.What we find in audits
At CleanIssue, we find SQL injection in roughly 15% of the applications we audit. The majority involve search queries with dynamic sorting or CSV exports with custom filters. Request your audit call to check your most exposed endpoints.
Related articles
Three adjacent analyses to keep exploring the same attack surface.
XSS explained: reflected, stored, DOM-based — how to protect yourself
The three types of Cross-Site Scripting explained with concrete examples, common attack vectors, and defenses to implement.
PostgreSQL and CVE-2018-1058: why search_path is still an underestimated risk
CVE-2018-1058 was not a classic SQL injection but a search_path and schema trust problem. Here is why this PostgreSQL flaw is still highly educational in 2026.
Python and Django: why CVE-2025-64459 should be taken seriously
CVE-2025-64459 showed that even a trusted ORM layer can expose SQL injection risk in specific conditions. Here is why this Django flaw should be taken seriously.
Sources
Editorial analysis based on official vendor, project, and regulator documentation.
Related services
If this topic maps to a real risk in your stack, these are the most relevant CleanIssue audits.