← Back to Security

SQL Injection

SecurityEntrysecuritysql

The Question

What is SQL injection and how do you prevent it?

What a Strong Answer Covers

  • parameterized queries
  • concrete example
  • never concatenation

Senior-Level Answer

SQL injection is a vulnerability where an attacker supplies input that is interpreted as SQL syntax rather than data, allowing them to manipulate queries, bypass authentication, exfiltrate data, or destroy database contents.

The root cause is string concatenation of user input into SQL queries. Consider: `query = "SELECT * FROM users WHERE username='" + username + "'"`. If the attacker submits `' OR '1'='1`, the query becomes `WHERE username='' OR '1'='1'` — which is always true and returns all users. With `'; DROP TABLE users; --`, they can append destructive statements.

Attack classes: authentication bypass (as above), data exfiltration (UNION-based injection to read other tables), blind SQL injection (boolean or time-based — infer data character by character when output isn't returned), and second-order injection (malicious payload stored in the DB and used in a later query).

The primary prevention is parameterized queries (prepared statements). The query structure is compiled separately from the data values, and the database driver handles proper escaping. In Python with psycopg2: `cursor.execute("SELECT * FROM users WHERE username = %s", (username,))`. The second argument is always treated as data, never as SQL syntax — even if it contains quotes, semicolons, or SQL keywords. This is not string formatting; the placeholder mechanism is separate from the query text.

ORMs like SQLAlchemy and Django ORM use parameterized queries internally, so standard ORM usage is safe. The danger reappears when using raw SQL within ORMs — `session.execute(text(f"WHERE name = '{name}'"))` is unsafe; `session.execute(text("WHERE name = :name"), {"name": name})` is safe.

Additional defenses in depth: least-privilege database accounts (the app user shouldn't have DROP or admin privileges), input validation (reject unexpected characters for structured inputs like IDs), stored procedures with parameterization, and WAFs as a backstop (not a substitute). ORMs reduce surface area but don't eliminate risk from raw queries or dynamic order-by clauses.

SQLMap is the canonical automated tool for detecting and exploiting SQL injection. Running it against your own app in a test environment is a standard audit step. OWASP lists SQLi as part of the A03:2021 Injection category.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly explains the mechanism (unsanitized input concatenated into SQL), gives a concrete example of the attack, and explains parameterized queries as the primary prevention.

3/3 — Strong Answer

All of the above plus: distinguishes multiple attack types (authentication bypass, data exfiltration, blind SQLi), explains why parameterized queries work mechanically (query structure compiled separately), discusses ORM safety and the raw query trap, and mentions defense-in-depth (least privilege, input validation).

Common Mistakes

  • Saying the fix is to 'sanitize' or 'escape' input — escaping is fragile and context-dependent. Parameterized queries are the correct fix; escaping is a fallback.
  • Not knowing why parameterized queries are safe mechanically — saying 'they prevent injection' without explaining that query structure and data are parsed separately.
  • Ignoring ORM-level raw query risks — candidates who say 'use an ORM and you're safe' without knowing that raw SQL within ORMs reintroduces the problem.
  • Not mentioning least-privilege as defense-in-depth — even if injection occurs, a DB user without DROP or SELECT on sensitive tables limits the blast radius.

Follow-Up Questions

  • What is blind SQL injection and how does it differ from classic injection? — Blind SQLi infers data without output — boolean (true/false response differences) or time-based (SLEEP/WAITFOR delays). Used when the app doesn't display query results.
  • Why is escaping/sanitizing input considered an inferior approach to parameterized queries? — Escaping is encoding-context-dependent and easy to get wrong. A single missed escape is exploitable. Parameterized queries eliminate the parsing ambiguity at the DB driver level.
  • How would you find SQL injection vulnerabilities in an existing codebase? — Static analysis (semgrep, Bandit for Python) to find string-formatted queries; dynamic testing with SQLMap; code review for raw SQL strings; grep for f-strings or % formatting in DB calls.
  • What is second-order SQL injection? — Malicious input is safely stored in the DB but later retrieved and interpolated into a new query unsafely. The injection vector and the execution are separated — harder to detect.

Related Questions

  • Authentication vs Authorization
  • JWT — 3 Parts, Signing, Revocation
  • CSRF
  • XSS
  • OAuth 2.0 — Authorization Code Flow

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout