What is SQL Injection?
SQL Injection happens when untrusted input (like user input) is mixed into a SQL query without proper handling — allowing an attacker to inject malicious SQL code.
🧨 This can lead to:
- Data leaks (stealing confidential data).
- Data destruction (deleting rows, dropping tables).
- Bypassing authentication.
- Gaining unauthorized access.
How Do You Prevent SQL Injection?
Here’s a full toolkit of defenses:
1. Use Prepared Statements (Parameterized Queries) 🚀 BEST Practice
✅ DO NOT build SQL by concatenating strings.
Bad (Vulnerable):
-- Unsafe (Directly embedding user input!)
"SELECT * FROM Users WHERE username = '" + userInput + "';"
Good (Safe with Parameters):
-- Safe prepared statement
SELECT * FROM Users WHERE username = ?;
- User input is treated as data, not code.
- SQL engine understands the query structure — no one can “inject” extra SQL.
✅ Examples in Code:
- Java (JDBC):
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM Users WHERE username = ?");
stmt.setString(1, userInput);
Python (with psycopg2 for PostgreSQL):
cursor.execute("SELECT * FROM Users WHERE username = %s", (userInput,))
2. Use ORM Frameworks
Frameworks like:
- Hibernate (Java)
- Entity Framework (C#)
- Sequelize (Node.js)
- Django ORM (Python)
✅ They generate SQL safely for you — making injections much harder.
3. Validate and Sanitize Input
✅ Validate:
- Check if input matches expected format:
- If you expect an integer, make sure it’s an integer.
- If you expect an email, validate email format.
✅ Sanitize:
- Strip or reject unexpected characters.
- Forbid semicolons, comments (
--
), or SQL keywords when not needed.
But note: Validation alone is NOT enough — always combine with prepared statements.
4. Use Least Privilege Principle
✅ Your application’s database user should have:
- Only the permissions it needs.
- No
DROP TABLE
, noDELETE
unless required.
🚫 Don’t connect your app as a superuser
or root
!
Even if someone manages an injection, they can’t destroy the whole database.
5. Disable Multiple Statements (Batching)
✅ Some database drivers can be configured to disallow multiple SQL statements in one call.
Example:
- Disable this in MySQL drivers (
allowMultiQueries=false
).
It blocks attacks like:
' OR 1=1; DROP TABLE Users; --
6. Error Handling and Logging
- Don’t show raw SQL errors to users — they can leak database structure!
✅ Always: - Log detailed errors internally.
- Show a generic error message to the user.
Summary of Defense Strategy
Defense | Purpose |
---|---|
Prepared Statements | Treat user input as data, not code. |
ORMs | Auto-generate safe SQL. |
Input Validation/Sanitization | Catch bad inputs early. |
Least Privilege Database User | Minimize damage even if attacked. |
Disable Multi-Statements | Prevent attacks with ; chaining. |
Safe Error Handling | Don’t leak database details to attackers. |
Real-Life Analogy
SQL Injection is like:
🧨 Allowing a stranger to write a custom command in your flight cockpit.
🚫 Prepared Statements are like: “I only let you press certain buttons, not type anything you want.”
In Short
Always use prepared statements — it’s the #1 safest, most reliable defense against SQL injection.