Lesson 6 of 8
Not started

Preventing SQL Injection with Prepared Statements

Why string-concatenated queries are dangerous and how PDO prepared statements eliminate SQL injection.

The problem

SQL injection is still one of the most damaging web vulnerabilities. It happens when user input is concatenated directly into a SQL string:

// NEVER do this
$sql = "SELECT * FROM users WHERE email = '" . $_POST['email'] . "'";
$result = $db->query($sql);

If an attacker submits ' OR '1'='1, the query logic collapses and they can read or destroy data.

The fix: prepared statements

Prepared statements separate the query structure from the data. The database compiles the query first, then binds values as pure data — they can never change the query's meaning.

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $_POST['email']]);
$user = $stmt->fetch();

Best practices

  • Always use parameterized queries (PDO or mysqli) for any value that comes from outside the application.

  • Use least-privilege database accounts — the web app user should not be able to DROP tables.

  • Validate and normalize input (expected type, length, format) as defense in depth.

  • Never expose raw database errors to users; log them server-side instead.

What it means for you

Prepared statements are the single highest-impact habit a PHP developer can build. Combined with the TLS and session hardening from earlier lessons, they close off the most common path attackers use to reach your data.