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.
Generate a random token and store it in the session when rendering the form.
Include the token as a hidden field in the form.
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.