Skip to content

Php Security

DodaTech 4 min read

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

What is the OWASP Top 10?

A list of the 10 most critical web application security risks, updated periodically. Includes injection, XSS, broken authentication, and sensitive data exposure.

Should I use filter_input or filter_var?

filter_var is more flexible. Use filter_input for convenience when directly filtering superglobals.

How do I secure API endpoints?

Use authentication (JWT), rate limiting, input validation, HTTPS, and CORS policies. Never trust the client.

What is Content Security Policy?

A browser security header that restricts which resources can load. Mitigates XSS and data injection attacks.

How do I prevent session fixation?

Regenerate session IDs after login with session_regenerate_id(true).

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