What is it?
Web application security is not optional. PHP applications are constantly probed for SQL injection, XSS, CSRF, and insecure file uploads. Each has a specific, proven defence that takes minutes to implement.
Why does it matter?
A single security vulnerability can expose every user's data, destroy your reputation, and result in legal liability. These four defences prevent the overwhelming majority of PHP web application attacks.
Learn SQL injection, XSS, CSRF, and secure file uploads — the top PHP security threats and their defences.
Real-World Use Cases
- 🔐 Login systems - Prepared statements prevent SQL injection in authentication queries. CSRF tokens prevent forged login attempts.
- 💬 Comment/review sections - htmlspecialchars prevents XSS when displaying user-submitted content like reviews, comments, and forum posts.
- 🖼️ Profile photo uploads - MIME type checking, random filename generation, and storing outside webroot prevent malicious file execution.
- 🛒 E-commerce checkout - CSRF protection on the order form prevents attackers from tricking logged-in users into placing orders they did not intend.
SQL Injection — Prepared Statements Fix
// VULNERABLE — attacker enters: ' OR 1=1 --
// This returns ALL users regardless of password!
$sql = "SELECT * FROM users WHERE email='$email' AND password='$pass'";
// FIXED — prepared statement with placeholders
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND password_hash = ?');
$stmt->execute([$_POST['email'], hash('sha256', $_POST['password'])]);
$user = $stmt->fetch();
XSS and CSRF Protection
// XSS: always escape before displaying in HTML
echo htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8');
// CSRF: generate token once, verify on every POST
session_start();
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
// In form:
Secure File Uploads
$allowedMime = ['image/jpeg', 'image/png', 'application/pdf'];
$maxSize = 5 * 1024 * 1024; // 5MB
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
die('Upload failed');
}
if ($_FILES['file']['size'] > $maxSize) {
die('File too large');
}
$mime = mime_content_type($_FILES['file']['tmp_name']);
if (!in_array($mime, $allowedMime)) {
die('Invalid file type');
}
$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$fileName = bin2hex(random_bytes(16)) . '.' . $ext;
$uploadDir = __DIR__ . '/uploads/';
if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $fileName)) {
die('Upload failed');
}
echo 'Upload successful';
Q: What is the single most important PHP security practice?
Never trust user input. Every value from $_GET, $_POST, $_COOKIE, and uploaded files can be malicious. Validate it, escape on output, and use prepared statements. These three habits prevent the majority of attacks.
Comments (0)
No comments yet. Be the first!
Leave a Comment