What Is SQL Injection? The Most Dangerous Web Attack Explained
SQL injection lets attackers manipulate database queries by inserting malicious SQL code into user inputs. It remains the most widespread and damaging web vulnerability — and one of the most preventable.
SQL injection (SQLi) is a web attack that lets an attacker insert — or "inject" — malicious SQL code into a query that the application sends to its database. If successful, the attacker can read sensitive data, modify or delete records, bypass authentication, and in some cases execute commands on the database server itself.
SQL injection has topped the [OWASP-web-application-attacks-explained) Top 10](/learning-center/gdpr-HIPAA-PCI-DSS-cybersecurity-compliance-frameworks-explained) list of web vulnerabilities for over a decade. Despite being well understood and easy to prevent, it remains the single most exploited web attack class.
How SQL Injection Works
Web applications typically build database queries by combining a template with user-supplied input. Consider a login form that checks a username and password:
SELECT * FROM users WHERE username = '[input]' AND password = '[input]';If the application inserts user input directly into the query without sanitising it, an attacker can close the string early and append their own SQL:
-- Attacker enters: admin' --
SELECT * FROM users WHERE username = 'admin' --' AND password = '';The -- is a SQL comment that makes the database ignore everything after it, including the password check. The query returns the admin user record — and the attacker is logged in without knowing the password.
Types of SQL Injection
Classic (In-band) SQLi
The attacker sends a malicious query and the result is returned directly in the application response. Two sub-types:
- Error-based: The attacker triggers database error messages that reveal schema information (table names, column names, database version)
- Union-based: Uses the SQL
UNIONoperator to append a secondSELECTand retrieve data from other tables
Blind SQLi
The application does not return query results or errors — but the attacker can still extract data by observing the application behaviour:
- Boolean-based: The attacker asks true/false questions ("Is the first character of the admin password greater than 'M'?") and infers the answer from whether the page looks different
- Time-based: Uses
SLEEP()orWAITFOR DELAY— if the page delays, the condition was true
Second-Order SQLi
The malicious payload is stored in the database first (e.g. in a username field) and executed later when another query retrieves and uses it. Harder to detect because the injection point and the trigger are separate.
Out-of-Band SQLi
Data is exfiltrated via a different channel (DNS lookup, HTTP request) rather than the application response. Used when in-band and blind techniques are too slow or unreliable.
Real-World Examples
| Incident | Year | Impact | |---|---|---| | Sony Pictures | 2011 | 1 million accounts exposed via SQLi on SonyPictures.com | | Heartland Payment Systems | 2008 | 130 million credit card numbers stolen | | Yahoo! Voices | 2012 | 450,000 credentials dumped via union-based SQLi | | TalkTalk | 2015 | 157,000 customer records exposed; £400,000 ICO fine |
How to Prevent SQL Injection
1. Use Prepared Statements (Parameterised Queries)
The most reliable defence. The query structure is fixed before user input is added — the database never interprets input as SQL code.
# Vulnerable
cursor.execute("SELECT * FROM users WHERE username = '" + username + "'")
# Safe — parameterised
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))2. Use an ORM
Object-Relational Mappers (Django ORM, SQLAlchemy, Hibernate, Sequelize) generate parameterised queries-web-application-attacks-explained) automatically, eliminating hand-written SQL in most cases.
3. Validate and Sanitise Input
- Whitelist expected characters (e.g. alphanumeric only for usernames)
- Reject or escape special characters:
',",;,--,/* - Never rely on input sanitisation-cross-site-scripting-explained) alone — use parameterised queries as the primary control
4. Apply Least Privilege
The database account used by the application should only have the permissions it needs — SELECT only for read operations, no DROP or EXEC privileges. This limits damage if an injection succeeds.
5. Use a Web Application Firewall (WAF)
A WAF can detect and block common SQLi patterns in HTTP requests. Useful as a defence-in-depth layer but not a substitute for proper coding.
6. Disable Detailed Error Messages in Production
Error messages that expose table names, column names, or database versions are a goldmine for attackers. Log errors server-side; show generic messages to users.
Detection and Testing
Security teams use these tools to detect SQLi:
| Tool | Type | Notes | |---|---|---| | sqlmap | Automated | Detects and exploits SQLi automatically; use only on authorised targets | | Burp Suite | Manual/Semi-auto | Intercept requests and modify parameters for manual testing | | OWASP-web-application-attacks-explained) ZAP | Automated | Free scanner with SQLi detection rules | | Nessus / Acunetix | Automated | Commercial vulnerability scanners with SQLi coverage |
SQL Injection vs NoSQL Injection
SQL injection targets relational databases (MySQL, PostgreSQL, MSSQL, Oracle). Modern NoSQL databases (MongoDB, CouchDB) are vulnerable to a similar attack called NoSQL injection, where attackers manipulate JSON query operators ($where, $gt) instead of SQL syntax. The defence is the same: validate inputs and use safe query APIs.
Key Takeaways
- SQL injection inserts malicious SQL into application queries to manipulate the database
- It can lead to authentication bypass, full data theft, data modification, and server compromise
- parameterised queries-web-application-attacks-explained) (prepared statements) are the primary and most reliable defence
- ORMs, input validation, least privilege, and WAFs provide defence-in-depth
- Despite being over 25 years old, SQLi remains one of the most commonly exploited vulnerabilities