SQL Injection Prevention

Use parameterized queries to prevent SQL injection attacks.

Code

General
// SAFE: PDO with prepared statements
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE users (id INTEGER, username TEXT)');
$pdo->exec('INSERT INTO users VALUES (1, "admin")');

// Prepare the query structure first, then bind data separately
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?');
$stmt->execute([$username]);
$results = $stmt->fetchAll();

"Safe query uses: SELECT * FROM users WHERE username = ?\n";
"Bound parameter: $username\n";
"The malicious input is treated as literal data, not SQL code.";

Parameters

User input (try a malicious payload)

Server

What is SQL Injection?

SQL injection occurs when user input is concatenated directly into SQL queries:

// DANGEROUS: Never do this!
$unsafe_query = "SELECT * FROM users WHERE username = '$username'";

If $username is admin' OR '1'='1, the query becomes:

SELECT * FROM users WHERE username = 'admin' OR '1'='1'

This returns ALL users because '1'='1' is always true.

Why Prepared Statements Work

ApproachUser Input Treated As
String concatenationExecutable SQL code
Prepared statementLiteral string data

With prepared statements, PDO sends the query structure and data separately. The database parses SELECT * FROM users WHERE username = ? first, then receives admin' OR '1'='1 as a string value - never as SQL code.

Named Parameters

You can also use named placeholders for clarity:

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

The Rule

Never concatenate user input into SQL queries. Always use PDO prepared statements.


More PHP Snippets