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
DROPtables.
- 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.