SQL Injection
SQL injection (SQLi) is one of the oldest and most devastating web security vulnerabilities. It occurs when an attacker can insert malicious SQL code into queries that your application sends to its database. A successful attack can read, modify, or delete any data in your database.
Despite being well-understood since the late 1990s, SQL injection remains in the OWASP Top 10 and was detected in 94% of applications tested in recent studies. The fix is simple—parameterized queries—yet developers continue to write vulnerable code.
How SQL Injection Works
SQL injection exploits the way applications build database queries. When user input is concatenated directly into SQL strings, attackers can escape the intended query context and inject their own SQL commands.
Vulnerable Code Example
// VULNERABLE: User input directly in SQL string
app.post('/login', async (req, res) => {
const { username, password } = req.body;
// This is the vulnerability - string concatenation
const query = `
SELECT * FROM users
WHERE username = '${username}'
AND password = '${password}'
`;
const user = await db.query(query);
if (user.rows.length > 0) {
res.json({ success: true, user: user.rows[0] });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});The Attack
An attacker enters a specially crafted username that changes the query logic:
Username: admin' --
Password: anything
Resulting query:
SELECT * FROM users
WHERE username = 'admin' --'
AND password = 'anything'
The -- comments out the password check!
Attacker logs in as admin without knowing the password.Types of SQL Injection
UNION-Based Injection
Uses UNION to combine results from another table, extracting data that shouldn't be accessible:
-- Original query for product search
SELECT name, price FROM products WHERE id = 1
-- Attacker input: 1 UNION SELECT username, password FROM users --
SELECT name, price FROM products WHERE id = 1
UNION SELECT username, password FROM users --
-- Returns all usernames and passwords!Blind SQL Injection
When error messages are hidden, attackers infer information through true/false responses or time delays:
-- Boolean-based: Does the first character of admin password = 'a'?
1 AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin') = 'a'
-- Time-based: If true, sleep for 5 seconds
1; IF (SELECT COUNT(*) FROM users WHERE username='admin') > 0
WAITFOR DELAY '0:0:5' --
-- Attacker measures response time to extract data bit by bitPrevention: Parameterized Queries
The only reliable defense is parameterized queries (prepared statements). They separate SQL code from data, making injection impossible.
Secure Code Examples
// Node.js with pg (PostgreSQL)
const query = 'SELECT * FROM users WHERE username = $1 AND password = $2';
const result = await db.query(query, [username, password]);
// Node.js with mysql2
const [rows] = await connection.execute(
'SELECT * FROM users WHERE username = ? AND password = ?',
[username, password]
);// Prisma ORM - automatically parameterized
const user = await prisma.user.findFirst({
where: {
username: username,
password: hashedPassword
}
});
// Raw queries in Prisma - still safe with template
const users = await prisma.$queryRaw`
SELECT * FROM users WHERE username = ${username}
`;Security Checklist
- Use parameterized queries for ALL database operations—no exceptions
- Use an ORM (Prisma, SQLAlchemy) that handles parameterization automatically
- Apply least-privilege database permissions
- Validate and sanitize all user input
- Never trust stored data—parameterize even when using data from your own database
Practice Challenges
View allCopy Pasta
A user search feature. The query looks a bit... concatenated.
NoSQL Injection
MongoDB queries with user input. What could go wrong?
Command Injection
A ping utility. But can you ping more than just hosts?
LDAP Injection
Enterprise login with LDAP. AI copied the query pattern.
XPath Injection
XML parsing with user input in XPath queries.
Related Articles
View allSQL Injection in Node.js: From Basics to Blind
SQL injection remains the #1 database vulnerability in 2025. While Node.js frameworks like Express make building APIs fast, they don't automatically protect your database queries. OWASP's 2024 API Secu...
The Hidden Dangers of AI-Generated SQL Queries
AI-generated SQL queries are silently introducing SQL injection vulnerabilities into production codebases at an alarming rate. According to Veracode's 2025 GenAI Code Security Report, AI coding assista...
Prompt Injection: The SQL Injection of the AI Era
Two decades ago, SQL injection forced the security industry to rethink how web applications handle user input. Today, prompt injection is doing the same for AI applications. OWASP ranks it #1 on their ...