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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs