PHP
CSRF token generation
Learn to generate a session-based CSRF token and verify it in forms.
What is CSRF?
CSRF (cross-site request forgery) tricks a user into submitting a form on another site without knowing. The browser sends the session cookie automatically, so the attacker can act as the user.
Defense: generate a random CSRF token per session and store it in $_SESSION. When the form is submitted, verify the token with hash_equals. The attacker cannot guess the token, so the forged request is blocked.
Token generation and session security
For a strong token use random_bytes(32); it produces cryptographically secure random bytes. bin2hex() turns these bytes into a hex string, easy to carry in a cookie or form.
Store the token under $_SESSION['csrf_token']. After a successful login call session_regenerate_id(true) to prevent session fixation. Enabling the httponly and samesite cookie options is also a good habit.
Exercise Generate and verify a CSRF token
Generate random bytes with random_bytes(32), convert them to a hex string with bin2hex, and store the result in $_SESSION['csrf_token']. Then assign the same token to $submitted and verify with hash_equals; print the result as "valid" or "invalid".
Show example solution
"invalid") . "\n";.
Example solution:
<?php
session_start();
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
$submitted = $token;
echo (hash_equals($_SESSION['csrf_token'], $submitted) ? "valid" : "invalid") . "\n";
Test yourself
-
What is the best defense against CSRF?
- Use a longer password
- A session-based CSRF token
- Use HTTPS
- Disable JavaScript
Show answer
A session-based CSRF token — Correct. A random session-bound token blocks forged requests.
-
Match the CSRF concepts
- random_bytes
- Produces random bytes
- bin2hex
- Converts to hex string
- hash_equals
- Constant-time comparison
- $_SESSION
- Server-side storage
-
Complete the hash_equals call
$valid = ____($_SESSION['csrf_token'], $submitted);
Show answer
$valid = hash_equals($_SESSION['csrf_token'], $submitted);
Next lesson: Security headers