PHP
Implementing CSRF Protection in PHP
Protect your web application from Cross-Site Request Forgery (CSRF) attacks by implementing a token-based verification system in your PHP forms, ensuring that only legitimate requests are processed.
<?php
session_start();
// Function to generate and store a CSRF token
function generateCsrfToken() {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
// Function to verify a CSRF token
function verifyCsrfToken($token) {
if (!isset($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $token)) {
return false;
}
return true;
}
// --- Example Usage ---
// 1. Display a form with a CSRF token
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$csrfToken = generateCsrfToken();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF Protected Form</title>
</head>
<body>
<h1>Update Profile</h1>
<form action="" method="POST">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="John Doe"><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="[email protected]"><br><br>
<button type="submit">Update</button>
</form>
</body>
</html>
<?php
}
// 2. Process form submission and verify CSRF token
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$submittedToken = $_POST['csrf_token'] ?? '';
if (!verifyCsrfToken($submittedToken)) {
// CSRF token mismatch or missing
http_response_code(403); // Forbidden
die('CSRF token validation failed. Possible attack detected!');
}
// If token is valid, process the form data
$name = htmlspecialchars($_POST['name'] ?? '');
$email = htmlspecialchars($_POST['email'] ?? '');
// --- IMPORTANT: Regenerate the token after a successful POST ---
// This prevents the same token from being reused in future requests
// and enhances security against "token replay" scenarios.
unset($_SESSION['csrf_token']);
generateCsrfToken(); // Generate a new one for subsequent forms
echo "<h1>Profile Updated Successfully!</h1>";
echo "<p>Name: " . $name . "</p>";
echo "<p>Email: " . $email . "</p>";
echo "<p><a href=\"\">Go back</a></p>";
}
?>
How it works: This PHP snippet demonstrates a fundamental method for protecting web applications against Cross-Site Request Forgery (CSRF) attacks using a token-based approach. On a GET request (when displaying a form), a unique CSRF token is generated using `bin2hex(random_bytes(32))` and stored in the user's session. This token is then embedded as a hidden field within the HTML form. Upon form submission (POST request), the received `csrf_token` from the form data is compared against the token stored in the session. If the tokens do not match or if the token is missing, the request is rejected with a `403 Forbidden` status. The `hash_equals()` function is used for constant-time string comparison to mitigate timing attacks. Regenerating the token after a successful POST request is crucial to prevent token reuse, making CSRF attacks significantly harder.