TL;DR
SQL injection is when attackers insert malicious database commands through your app's input fields. If you build SQL queries by concatenating user input, attackers can manipulate those queries to read, modify, or delete your entire database. The fix is simple: use parameterized queries or an ORM like Prisma. These treat user input as data, never as SQL commands.
The Simple Explanation
Imagine a login form that checks credentials like this:
const query = SELECT * FROM users WHERE email = '${email}' AND password = '${password}';
A normal user enters their email and password. But an attacker enters this as the password:
' OR '1'='1
The resulting query becomes:
SELECT * FROM users WHERE email = 'user@example.com' AND password = '' OR '1'='1'
Since '1'='1' is always true, this returns all users. The attacker just bypassed authentication.
What Attackers Can Do
SQL injection is in the OWASP Top 10 and has been responsible for some of the largest data breaches in history. Attackers can:
- Read data: Extract usernames, passwords, credit cards, personal info
- Modify data: Change prices, grant admin access, alter records
- Delete data:
DROP TABLE users;destroys everything - Access server: Some databases allow executing system commands
Real impact: SQL injection attacks cost businesses millions per incident. Never trust user input in SQL queries.
How to Prevent SQL Injection
1. Use Parameterized Queries
Pass user input as parameters, not as part of the SQL string:
const result = await client.query( 'SELECT * FROM users WHERE email = $1 AND password = $2', email, hashedPassword );
2. Use an ORM
ORMs like Prisma, Drizzle, and Sequelize use parameterized queries automatically:
const user = await prisma.user.findUnique({ where: { email: email } }); // Prisma handles parameterization internally
3. Avoid Raw Queries with User Input
Most ORMs offer raw query methods. If you use them, be careful to still use parameters.
What is the best way to prevent SQL injection?
Use parameterized queries (also called prepared statements). Instead of building SQL strings with user input, pass values as parameters. ORMs like Prisma, Drizzle, and Sequelize handle this automatically. Never use string concatenation or template literals to build SQL queries with user data.
Does using an ORM protect against SQL injection?
Yes, ORMs like Prisma, Drizzle, TypeORM, and Sequelize use parameterized queries by default. However, most ORMs also offer raw query methods that can be vulnerable if misused. Always use the ORM's built-in query builders rather than raw SQL with user input.
Can SQL injection delete my entire database?
Yes. An attacker can inject commands like DROP TABLE or DELETE FROM. They can also read sensitive data, modify records, or even gain access to the underlying server in some cases. SQL injection is consistently rated as one of the most critical web vulnerabilities.