What is an SQL Injection vulnerability?
A code injection technique that exploits vulnerabilities in database queries. Attackers can read, modify, or delete database data. Prevented by using parameterized queries.
Understanding SQL Injection
SQL injection occurs when user input is concatenated into SQL queries without proper sanitization. Attackers can manipulate queries to bypass authentication, extract data, modify records, or even execute system commands. It remains one of the most dangerous and common vulnerabilities, responsible for some of the largest data breaches in history.
Examples
- Login bypass: ' OR '1'='1' --
- Data extraction: ' UNION SELECT username, password FROM users --
- Database manipulation: '; DROP TABLE users; --
- Blind SQL injection using time delays
How to Prevent
- Use parameterized queries / prepared statements for ALL database queries
- Use ORM frameworks (Prisma, Sequelize, SQLAlchemy) which parameterize by default
- Apply input validation as defense-in-depth (but never as the only defense)
- Use least privilege database accounts - apps should never connect as root
- Implement WAF rules to detect and block SQL injection patterns
- Escape special characters if you absolutely must use dynamic queries
- Regular security testing with tools like sqlmap
Code Examples
Vulnerable Login Query
The vulnerable code concatenates user input directly into the SQL query. The secure version uses parameterized queries where user input is treated as data, not code.
// VULNERABLE: User input directly in query
const query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
db.query(query);
// Attacker inputs: username = "admin'--"
// Resulting query: SELECT * FROM users WHERE username = 'admin'--' AND password = ''
// The -- comments out the password check, logging in as admin // SECURE: Using parameterized queries
const query = "SELECT * FROM users WHERE username = ? AND password = ?";
db.query(query, [username, password]);
// Or with an ORM like Prisma
const user = await prisma.user.findFirst({
where: { username, password: hashedPassword }
}); Node.js with PostgreSQL
// VULNERABLE
app.get('/user/:id', async (req, res) => {
const result = await pool.query(
`SELECT * FROM users WHERE id = ${req.params.id}`
);
res.json(result.rows);
}); // SECURE: Parameterized query
app.get('/user/:id', async (req, res) => {
const result = await pool.query(
'SELECT * FROM users WHERE id = $1',
[req.params.id]
);
res.json(result.rows);
}); Real-World Incidents
Equifax Data Breach
2017Attackers exploited an Apache Struts vulnerability that allowed SQL injection, exposing personal data of 147 million people.
Impact: $700 million settlement, CEO resignation, massive reputation damage
Heartland Payment Systems
2008SQL injection attack exposed 134 million credit card numbers, one of the largest breaches at the time.
Impact: $140 million in compensation payments
Sony Pictures
2011SQL injection attack on PlayStation Network compromised 77 million user accounts.
Impact: 23-day service outage, estimated $171 million in costs
Worried about SQL Injection in your app?
Our security audits identify vulnerabilities like this before attackers do. Get expert manual review of your codebase.