SQL Injection: What It Is and How to Prevent It
SQL injection has been the #1 web vulnerability for decades. Yet it keeps appearing in production apps. Here's everything you need to know.
What Is SQL Injection?
It's when user input is concatenated directly into a SQL query, letting attackers rewrite the query.
Vulnerable Code
# NEVER DO THIS
username = request.form['username']
user = db.execute(
f"SELECT * FROM users WHERE username='{username}'"
).fetchone()
If the attacker enters ' OR '1'='1, the query becomes:
SELECT * FROM users WHERE username='' OR '1'='1'
This returns every user. The attacker is now logged in.
More Dangerous Payloads
-- Drop a table:
username: '; DROP TABLE users; --
-- Dump all passwords:
username: ' UNION SELECT email, password, null FROM users --
-- Read files (MySQL):
username: ' UNION SELECT load_file('/etc/passwd'), null, null --
The Fix: Parameterised Queries
Always pass user data as separate parameters — never concatenate:
# SAFE — always use this pattern
username = request.form['username']
user = db.execute(
"SELECT * FROM users WHERE username=?",
(username,) # ← the DB driver handles escaping
).fetchone()
The ? is a placeholder. The database driver escapes the value before substituting it — so ' OR '1'='1 is treated as a literal string, not SQL syntax.
ORM Safety
ORMs like SQLAlchemy use parameterised queries by default:
user = User.query.filter_by(username=username).first() # safe
But raw SQL through an ORM can still be vulnerable:
# DANGEROUS even inside an ORM
db.session.execute(f"SELECT * FROM users WHERE username='{username}'")
# SAFE
db.session.execute(
"SELECT * FROM users WHERE username=:name",
{"name": username}
)
Finding Injection Vulnerabilities
# sqlmap — automated detection
pip install sqlmap
sqlmap -u "https://example.com/login" --data "username=test&password=test"
Other Mitigations
- Least Privilege: your DB user shouldn't have DROP or FILE permissions
- WAF: a Web Application Firewall can block known payloads
- Input Validation: validate types and lengths before queries
- Error Handling: never expose raw DB errors to users
Parameterised queries solve 99% of SQL injection. There's no excuse not to use them.
0 Comments
Join the conversation
No comments yet. Be the first!