iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

SQL Injection

SQL injection is what happens when user input is concatenated into a query as raw text — the attacker can change the meaning of the SQL the app intended to run.

The vulnerable pattern

PHP — DON'T
// $_POST['email'] is attacker-controlled
$sql = "SELECT * FROM users WHERE email = '" . $_POST['email'] . "'";
mysqli_query($conn, $sql);

If email is ' OR 1=1 --, the resulting SQL becomes:

SQL
SELECT * FROM users WHERE email = '' OR 1=1 -- '

Now it returns every row. With UNION the attacker can leak other tables; with ;DROP they can destroy them.

The fix — parameterised queries

PHP — Safe
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$_POST['email']]);

The driver sends the SQL and the parameter separately. The DB never tries to parse the parameter as SQL — injection becomes impossible.

Same idea, other languages

LanguageForm
Python (psycopg)cur.execute("… WHERE email = %s", (email,))
Node (pg)client.query("… WHERE email = $1", [email])
Java (JDBC)PreparedStatement + setString
Laravel EloquentUser::where('email', $email) — auto-binds.

Defence in depth

  • Use the app's ORM or query builder — most bind automatically.
  • Give the app's DB user the least privileges it needs (no DROP, no GRANT).
  • Use a WAF / IDS for anomaly detection.
  • Treat all input as hostile, including from authenticated users.
Tip: If you ever find yourself thinking "I'll just escape the quotes myself", stop. There's no safe hand-roll. Use the driver's bound parameters every single time.

Example

Example
-- Use parameters, never concatenate user input:
SELECT * FROM users
WHERE email = ? AND password_hash = ?;
Try it Yourself »

Exercise

The fix for SQL injection is to use…

statements (with bound parameters)

Test yourself

Q1. SQL injection happens because…
Q2. The fix is…
Q3. Defence-in-depth includes…

Discussion

Loading…