SyntaxStudy
Sign Up
PHP CSRF Protection Basics
PHP Intermediate 9 min read

CSRF Protection Basics

Cross-Site Request Forgery (CSRF) tricks an authenticated user's browser into sending a malicious request to your application. CSRF tokens prevent this by requiring a secret value that only your server and the legitimate form page know.

  1. Generate a random token and store it in the session when rendering the form.
  2. Include the token as a hidden field in the form.
  3. On submission, compare the submitted token with the session token.
Example
<?php
session_start();

// Generate token when rendering the form
function generateCsrfToken(): string
{
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

// Validate token on form submission
function validateCsrfToken(string $submittedToken): bool
{
    $sessionToken = $_SESSION['csrf_token'] ?? '';
    // hash_equals is timing-safe
    return hash_equals($sessionToken, $submittedToken);
}

// In your form template:
$token = generateCsrfToken();
// <input type="hidden" name="csrf_token" value="<?= $token ?>">

// In your form handler:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $submitted = $_POST['csrf_token'] ?? '';
    if (!validateCsrfToken($submitted)) {
        http_response_code(403);
        die('Invalid CSRF token');
    }
    // Rotate token after use
    unset($_SESSION['csrf_token']);
    // ... process form
}
Pro Tip

Tip: Always use hash_equals() instead of === or == when comparing CSRF tokens. It performs a timing-safe comparison that prevents timing attacks that could allow an attacker to guess the token one byte at a time.