Php Security
title: PHP Security — Complete Guide to Securing PHP Applications description: 'Learn PHP security: XSS prevention, SQL injection protection, CSRF tokens, password hashing, input validation, file upload security, and HTTPS configuration.' date: 2026-06-28 lastmod: 2026-06-28 weight: 39 tags: [backend, php]
PHP security protects applications against XSS, SQL injection, CSRF, session hijacking, and other common vulnerabilities through proper input handling, escaping, and validation.
## What You'll Learn
By the end of this tutorial, you'll prevent XSS with htmlspecialchars, protect against SQL injection with prepared statements, implement CSRF tokens, securely hash passwords, and validate file uploads.
## Why Security Matters
Security vulnerabilities lead to data breaches, financial loss, and reputation damage. OWASP lists injection and XSS as top web risks. Proactive security is essential for production applications.
## Real-World Use
An e-commerce site uses prepared statements for all database queries, CSRF tokens for forms, bcrypt password hashing, and Content Security Policy headers to prevent XSS attacks.
## Security Learning Path
```mermaid
flowchart LR
A[Forms] --> B[SQL Injection]
B --> C[XSS]
C --> D[CSRF]
D --> E[Password Hashing]
A --> F{You Are Here}
style F fill:#f90,color:#fff
SQL Injection Prevention
<?php
// UNSAFE: vulnerable to SQL injection
$sql = "SELECT * FROM users WHERE email = '" . $_POST["email"] . "'";
// SAFE: use prepared statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST["email"]]);
// SAFE: named parameters
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(["email" => $_POST["email"]]);
XSS Prevention
<?php
// UNSAFE: renders raw HTML/JS
echo "<h1>" . $userInput . "</h1>";
// SAFE: escape HTML
echo "<h1>" . htmlspecialchars($userInput, ENT_QUOTES | ENT_HTML5, "UTF-8") . "</h1>";
// SAFE when you need some HTML (use a library like HTMLPurifier)
$safeHtml = strip_tags($userInput, "<b><i><em><strong>");
echo "<div>" . $safeHtml . "</div>";
CSRF Protection
<?php
session_start();
// Generate token
if (empty($_SESSION["csrf_token"])) {
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
}
// Include in form
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION["csrf_token"] . '">';
// Validate on submission
if (!hash_equals($_SESSION["csrf_token"], $_POST["csrf_token"] ?? "")) {
die("CSRF validation failed");
}
Password Hashing
<?php
// Hashing (registration)
$hash = password_hash($_POST["password"], PASSWORD_BCRYPT, ["cost" => 12]);
// Verification (login)
if (password_verify($_POST["password"], $storedHash)) {
// Login successful
}
// Check if rehash needed
if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ["cost" => 12])) {
$newHash = password_hash($_POST["password"], PASSWORD_BCRYPT);
// Update stored hash
}
Input Validation
<?php
function validateInput(string $input, string $type): bool {
return match($type) {
"email" => filter_var($input, FILTER_VALIDATE_EMAIL) !== false,
"url" => filter_var($input, FILTER_VALIDATE_URL) !== false,
"int" => filter_var($input, FILTER_VALIDATE_INT) !== false,
"ip" => filter_var($input, FILTER_VALIDATE_IP) !== false,
default => true,
};
}
// Sanitization
$email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL);
$name = strip_tags($_POST["name"]);
Common Mistakes
1. Trusting User Input
Never trust $_GET, $_POST, $_COOKIE, $_FILES, or $_SERVER values. Validate and sanitize everything.
2. Not Using HTTPS
All data transmitted without HTTPS is visible to attackers. Always use TLS/SSL certificates.
3. Storing Passwords in Plain Text
Always hash passwords with password_hash(). Never use MD5 or SHA1 for passwords.
4. Exposing Debug Information
Disable display_errors in production. Log errors to files, not the browser.
5. Not Validating File Uploads
Check file type, size, and extension. Store uploaded files outside the web root with randomized names.
Practice Questions
1. How do you prevent SQL injection in PHP?
Use prepared statements with PDO or MySQLi. Never concatenate user input into SQL queries.
2. What is XSS and how do you prevent it?
Cross-Site Scripting injects malicious scripts. Prevent by escaping output with htmlspecialchars().
3. How do CSRF tokens work?
A unique token embedded in forms is validated on submission. The attacker can't guess the token.
4. Why use bcrypt for password hashing?
bcrypt is slow (resists brute force), includes a salt, and adapts to faster hardware with cost factor.
5. Challenge: Create a secure file upload handler that validates file types and stores files safely.
<?php
$allowedTypes = ["image/jpeg", "image/png", "application/pdf"];
$maxSize = 5 * 1024 * 1024; // 5MB
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (!in_array($_FILES["file"]["type"], $allowedTypes)) {
die("Invalid file type");
}
if ($_FILES["file"]["size"] > $maxSize) {
die("File too large");
}
$ext = pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION);
$newName = bin2hex(random_bytes(16)) . "." . $ext;
move_uploaded_file($_FILES["file"]["tmp_name"], "/secure/uploads/$newName");
echo "File uploaded";
}
FAQ
Mini Project: Secure Form Handler
Build a contact form with CSRF protection, input validation, and XSS prevention.
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (!hash_equals($_SESSION["csrf_token"], $_POST["csrf_token"] ?? "")) {
die("Invalid token");
}
$name = htmlspecialchars(strip_tags($_POST["name"]), ENT_QUOTES, "UTF-8");
$email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL);
$message = htmlspecialchars(strip_tags($_POST["message"]), ENT_QUOTES, "UTF-8");
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
die("Invalid email");
}
$safeMessage = "From: $name ($email)\n\n$message";
mail("admin@example.com", "Contact Form", $safeMessage);
echo "Message sent securely";
}
What's Next
PHP Upload PHP Performance PHP Docker Deployment
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro