SQL Injection (SQLi)
A type of vulnerability where an attacker can interfere with the queries that an application makes to its database.
Detailed Explanation
SQLi occurs when user input is directly concatenated into a SQL query string. An attacker can input SQL commands (like `' OR 1=1 --`) to bypass authentication, view private data, or even delete the entire database. The primary defense is using 'Parameterized Queries' or 'Prepared Statements,' which treat user input as data rather than executable code.
Quick Summary
SQL injection lets an attacker rewrite database queries by feeding crafted input into a query the app builds via string concatenation. Outcomes range from auth bypass to dumping the entire database. The fix is well-known: parameterized queries.
Key Takeaways
- The root cause is always the same: untrusted data concatenated into a query string instead of bound as a parameter.
- Parameterized queries (prepared statements) send query and data on separate channels, the database never confuses one for the other.
- ORMs (Prisma, SQLAlchemy, ActiveRecord) parameterize by default, but raw SQL methods (.raw, .query, .execute with strings) reintroduce the risk.
- Defense in depth: least-privilege DB users, allowlist input validation, WAFs, and query logging.
- Variants: classic in-band, blind (no output, infer via timing or boolean), and out-of-band (data exfiltrated via DNS or HTTP).
When to use it
- Code review red flags: any string concatenation that builds SQL.
- Pentest scope items, even modern apps still have SQLi when raw queries slip into hot paths.
- Security training, as the canonical example of trust-the-input bugs.
- Triage of ORM escape hatches in legacy codebases.
Common Mistakes
- Trying to fix SQLi by escaping quotes manually, attackers find ways around homemade escaping.
- Whitelisting strings instead of using parameters; works until edge cases ship.
- Trusting numeric inputs as "safe", number-shaped inputs from user-controlled sources still need parameterization in many drivers.
- Building dynamic ORDER BY or table names from user input; parameters cover values, not identifiers, use allowlists.
SQL Injection (SQLi), Frequently Asked
Are ORMs safe from SQL injection?
Mostly. Standard query builders parameterize. Escape hatches that accept raw SQL strings (Prisma's `$queryRawUnsafe`, ActiveRecord's `.find_by_sql`) reintroduce the risk if you interpolate user input into them.
Can I prevent SQLi with input validation alone?
No. Validation reduces the attack surface but doesn't fix the root cause. Parameterized queries do, and they work even when validation is wrong or missing. Use both; never skip parameters.
What about NoSQL injection?
Same shape, different syntax, attackers inject operators ($ne, $gt) into Mongo queries built from objects derived from user input. The defense is the same: never trust deserialized objects from untrusted sources; coerce types and validate shapes.