PHP - CSRF Token Implementation in PHP

Cross-Site Request Forgery, commonly known as CSRF, is a type of web security vulnerability where an attacker tricks a user into performing unintended actions on a web application in which they are already authenticated. This can lead to serious consequences such as unauthorized fund transfers, password changes, or data manipulation.

CSRF token implementation in PHP is a defensive technique used to protect web applications from such attacks by ensuring that every sensitive request is legitimate and intentionally made by the user.

Understanding the Problem

In a typical CSRF attack, a user logs into a trusted website. While still authenticated, they are tricked into visiting a malicious website. This malicious site sends a request to the trusted application using the user’s active session, making it appear as though the request came from the user.

Since the server cannot distinguish between a legitimate request and a forged one, the action is executed unless proper protection is in place.

Concept of CSRF Tokens

A CSRF token is a unique, unpredictable value generated by the server and associated with a user’s session. This token is included in forms or requests and validated by the server before processing the request.

Because the attacker cannot access or predict this token, they cannot forge a valid request.

Token Generation

In PHP, a CSRF token is usually generated using secure random functions and stored in the session.

Example:

session_start();

if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

This code creates a secure token and stores it in the user's session. The token remains consistent for that session unless regenerated.

Embedding the Token in Forms

The generated token must be included in HTML forms so that it is sent along with the request.

Example:

<form method="POST" action="process.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <button type="submit">Submit</button>
</form>

This ensures that every form submission carries the token.

Token Validation

When the form is submitted, the server compares the received token with the one stored in the session.

Example:

session_start();

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('Invalid CSRF token');
}

If the tokens do not match, the request is rejected. This prevents unauthorized or forged requests.

Token Regeneration

For better security, tokens can be regenerated periodically or after each successful request.

Example:

$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

This reduces the risk of token reuse and enhances protection.

Handling AJAX Requests

CSRF protection is also necessary for asynchronous requests. In such cases, the token is usually sent in request headers.

Example:

fetch('process.php', {
    method: 'POST',
    headers: {
        'X-CSRF-TOKEN': 'token_value_here'
    }
});

The server then validates this token similarly to form submissions.

Best Practices

To ensure effective CSRF protection:

  • Always use secure random functions to generate tokens

  • Store tokens in server-side sessions

  • Include tokens in all state-changing requests (POST, PUT, DELETE)

  • Avoid using predictable values

  • Regenerate tokens when necessary

  • Use HTTPS to prevent token interception

Limitations

CSRF tokens are effective but must be implemented correctly. They do not protect against other attacks such as Cross-Site Scripting (XSS). If an attacker can execute scripts on the page, they may be able to steal the token.

Therefore, CSRF protection should be combined with other security measures.

Conclusion

CSRF token implementation in PHP is a critical security practice for protecting web applications from unauthorized actions. By generating unique tokens, embedding them in requests, and validating them on the server, developers can ensure that only legitimate user actions are processed. Proper implementation significantly reduces the risk of exploitation and strengthens the overall security of the application.