← Back to Labs

SQL Injection Boundary Lab

Feed the same payload into unsafe string-built SQL and a prepared statement, then watch the parser and outcome diverge.

scenario
Login bypass
query shape
boolean rewrite

Endpoint: POST /login · Input: email = ' OR 1=1 --

incoming bytes
email = ' OR 1=1 --

One apostrophe closes the original string, the injected boolean changes the meaning, and the comment discards the tail.

unsafe build
String interpolation
SELECT id, email, is_admin
FROM users
WHERE email = '' OR 1=1 --'
  AND active = true
parser view
Attacker bytes become grammar

STRING('') | OR | 1=1 | COMMENT

execution result
Unsafe path

Predicate becomes always true. The app may accept the first active row or expose a broad result set.

safe build
Prepared statement
Parse: SELECT id, email, is_admin
FROM users
WHERE email = $1
  AND active = $2
Bind: [$1 = "' OR 1=1 --", $2 = true]
parser view
Input stays data

PLACEHOLDER($1) | VALUE("' OR 1=1 --")

execution result
Safe path

The query compares email to the literal string `\' OR 1=1 --` and usually returns zero rows.

defence posture
Primary fix plus blast-radius control

A read-only role still would not make this safe, but it could stop the same bug from turning into writes or destructive follow-on queries.

Step 1 / 5Untrusted input reaches a query builder

The application receives bytes from a request. Nothing bad has happened yet. The risk starts when those bytes are allowed to shape SQL text.

Scenario focus: boolean rewrite

Arrow keys to navigate · R to reset

Tap dots to jump to any step

Read the full article →Take the quiz →