Web Security
Beginner
1 min read
Parameterised Queries and Prepared Statements
Example
<?php
// SAFE: PDO prepared statements
$dsn = 'mysql:host=localhost;dbname=myapp;charset=utf8mb4';
$pdo = new PDO($dsn, 'app_web', getenv('DB_PASS'), [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // use true prepared statements
]);
// Named placeholders (recommended for clarity)
$stmt = $pdo->prepare(
'SELECT id, username, email FROM users WHERE username = :username AND active = :active'
);
$stmt->execute(['username' => $_POST['username'], 'active' => 1]);
$user = $stmt->fetch();
// ----------------------------------------------------------------
// Python (psycopg2 — PostgreSQL)
// ----------------------------------------------------------------
// import psycopg2
// conn = psycopg2.connect(DATABASE_URL)
// cur = conn.cursor()
// cur.execute(
// "SELECT id, email FROM users WHERE username = %s AND active = %s",
// (username, True) # values passed separately — safe
// )
// ----------------------------------------------------------------
// Node.js (pg — PostgreSQL)
// ----------------------------------------------------------------
// const { rows } = await pool.query(
// 'SELECT id, email FROM users WHERE username = $1 AND active = $2',
// [username, true]
// );
// ----------------------------------------------------------------
// Dynamic ORDER BY — allowlist approach
// ----------------------------------------------------------------
$allowed_columns = ['username', 'email', 'created_at'];
$order_by = in_array($_GET['sort'] ?? '', $allowed_columns, true)
? $_GET['sort']
: 'created_at';
$stmt = $pdo->prepare("SELECT * FROM users ORDER BY {$order_by} DESC");
$stmt->execute();
Related Resources
Web Security Reference
Complete tag & property list
Web Security How-To Guides
Step-by-step practical guides
Web Security Exercises
Practice what you've learned
More in Web Security