PHP
CSRF Protection with Synchronizer Token Pattern (PHP)
Implement robust Cross-Site Request Forgery (CSRF) protection in PHP using the synchronizer token pattern to secure forms and critical actions from malicious requests.
<?php
session_start();
// Generate a CSRF token
function generateCsrfToken(): string {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
// Validate a CSRF token
function validateCsrfToken(string $token): bool {
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
// Example Usage:
// 1. On form display:
// echo '<form action="process.php" method="POST">';
// echo '<input type="hidden" name="csrf_token" value="' . htmlspecialchars(generateCsrfToken()) . '">';
// echo '<input type="text" name="data">';
// echo '<button type="submit">Submit</button>';
// echo '</form>';
// 2. On form submission (process.php):
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || !validateCsrfToken($_POST['csrf_token'])) {
// CSRF token is missing or invalid
http_response_code(403);
die("CSRF token validation failed. Request blocked.");
}
// Token is valid, process the request
echo "CSRF token is valid. Processing data: " . htmlspecialchars($_POST['data'] ?? 'No data') . "
";
// After successful processing, regenerate token for next request (optional but good practice for single-use tokens)
unset($_SESSION['csrf_token']);
} else {
// Display the form with a new token
$token = generateCsrfToken();
echo "Please submit the form:
";
echo '<form action="" method="POST">';
echo '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">';
echo '<label for="data_field">Data:</label>';
echo '<input type="text" id="data_field" name="data" value="Some value">';
echo '<button type="submit">Submit Securely</button>';
echo '</form>';
}
?>
How it works: This PHP snippet implements CSRF protection using the synchronizer token pattern. A unique token is generated and stored in the user's session. This token is then embedded into forms as a hidden field. Upon submission, the server verifies if the submitted token matches the one in the session. If they don't match, the request is rejected, preventing malicious cross-site requests. The token is also regenerated or removed after use for enhanced security.