SQL injection (SQLi) has been topping the OWASP Top 10 list of web vulnerabilities for over two decades. Despite being well-documented, it still causes massive data breaches every year. In this guide, we’ll break down exactly how SQL injection works, show you real attack examples, and walk you through practical defenses any developer or admin can implement.
What Is SQL Injection?
SQL injection is an attack technique where a hacker inserts malicious SQL code into an input field (like a login form or search box) that gets executed by the backend database. Because the application fails to properly validate or sanitize user input, the database treats the attacker’s code as a legitimate command.
The result? Attackers can read sensitive data, bypass authentication, modify or delete records, and in some cases take over the entire server.
How SQL Injection Works: Step by Step
Let’s say a website has a login form. The backend code might look like this:
SELECT * FROM users WHERE username='[input]' AND password='[input]';
A normal user types their username and password, and the query runs cleanly. But an attacker types this into the username field:
' OR '1'='1
The resulting SQL query becomes:
SELECT * FROM users WHERE username='' OR '1'='1' AND password='anything';
Since '1'='1' is always true, the database returns all users — and the attacker logs in as the first user in the database, often the administrator.
Types of SQL Injection
1. In-Band SQLi (Classic)
The attacker uses the same communication channel to launch the attack and gather results. This is the most common type. The two subtypes are Error-Based (using database error messages to extract info) and Union-Based (using UNION SQL operators to combine results from multiple SELECT statements).
2. Blind SQLi
The application doesn’t return query results to the attacker, but still behaves differently based on whether the query is true or false. Attackers ask the database yes/no questions — like “Is the first letter of the admin password ‘a’?” — and slowly reconstruct data. This is slower but just as dangerous.
3. Out-of-Band SQLi
The attacker uses a different channel (like DNS or HTTP requests) to receive the data. This is rarer and depends on server capabilities, but extremely hard to detect.
Real-World SQL Injection Breaches
Heartland Payment Systems (2008) — $130 Million in Damages
SQL injection was used to plant malware inside Heartland’s payment processing network. Attackers stole over 130 million credit and debit card numbers. It was the largest data breach in U.S. history at the time. The attacker, Albert Gonzalez, was sentenced to 20 years in prison.
Sony PlayStation Network (2011)
A SQL injection attack compromised 77 million PSN accounts, exposing names, addresses, email addresses, birth dates, and potentially credit card data. Sony was forced to shut down PSN for 23 days, costing an estimated $171 million.
TalkTalk (2015) — £400,000 Fine
A SQL injection attack on UK telecom TalkTalk exposed data for 157,000 customers. The attackers were teenagers. TalkTalk received a record fine from the UK Information Commissioner’s Office (ICO) for failing to implement basic security measures.
How to Prevent SQL Injection: Practical Defenses
1. Use Parameterized Queries (Prepared Statements)
This is the #1 defense. Instead of building SQL strings dynamically, use placeholders:
// PHP PDO example
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
The database treats the user input as pure data — never as executable code.
2. Use an ORM (Object-Relational Mapper)
Frameworks like Django, Laravel, or Ruby on Rails abstract SQL queries and use parameterized queries by default. If you’re using these, you get significant protection out of the box — as long as you don’t bypass the ORM with raw queries.
3. Input Validation and Whitelisting
Validate and sanitize all user inputs. If a field should only contain numbers, reject anything that isn’t a number. Use a whitelist approach — define what IS allowed, not just what isn’t.
4. Least Privilege Database Accounts
Your web application’s database user should only have the permissions it absolutely needs. If it only reads data, don’t give it INSERT, UPDATE, DELETE, or DROP permissions. This limits damage if an injection attack succeeds.
5. Web Application Firewall (WAF)
A WAF like Cloudflare, ModSecurity, or AWS WAF can detect and block SQL injection patterns before they reach your application. It’s not a replacement for proper coding, but it adds an important layer of defense.
6. Error Handling
Never display raw database errors to users. Attackers use error messages to map your database structure. Log errors internally and show users a generic message like “An error occurred.”
Test Your Own Site: Free Tools
Before attackers test your site, you should test it yourself. These tools are used by security professionals:
- SQLMap — the most popular open-source SQL injection automation tool. Run it against your own applications in a test environment.
- OWASP ZAP — a free security scanner that includes SQL injection detection.
- Burp Suite (Community Edition) — intercept and manipulate web traffic to manually test for SQLi.
Important: Only test applications you own or have written permission to test. Unauthorized testing is illegal.
Summary
SQL injection is a 25-year-old vulnerability that continues to cause billion-dollar breaches. The fix is straightforward: use parameterized queries, validate inputs, apply least privilege, and add a WAF. There’s no excuse in 2025 for shipping applications vulnerable to SQLi. Test your own code, train your developers, and make security part of your development process from day one.