Using token in vanilla PHP for CSRF

Frameworks like Django and Laravel have CSRF Protection by default. Most of use it by their default behaviour in our jinja2 / blade templates and it just works. Super easy to make use of it and we need to write 0 code to implement the security bit on the form submission. Latest Laravel 11 Video Explanation on CSRF.

But let's say you don't want to use a full-blown framework for a dead-simple scenario where the entire PHP application is just one form of sorts ... and still want to make use to CSRF - then, you would need to write it from scratch and implement the security bit.

touch form.php
touch form-post.php
code .

form.php

<?php
session_start();
$_SESSION['token'] = md5(uniqid(mt_rand(), true));
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form</title>
</head>
<body>
    <form method="post" action="form-post.php">
        <input type="email" name="email" id="email" required />
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?? '' ?>" />
        <button type="submit">Submit</button>
    </form>    
</body>
</html>

form-post.php

<?php
session_start();

$token = htmlspecialchars($_POST['token']);

if (!isset($token) || $token !== $_SESSION['token'])
{
    die("Attack attempted");
}

# Re-Generate token so that hitting the refresh button invalidates the form submission
$_SESSION['token'] = md5(uniqid(mt_rand(), true));
?>
<h1>Form POSTed</h1>
<?php
echo "<pre>POST : \n";
print_r($_POST); echo "\n";
echo "SESSION :\n";
print_r($_SESSION);
echo "</pre>"
?>
php -S localhost:8004

Now browse to http://localhost:8004/form.php and submit and your should see a Form POSTed and now if you hit the refresh button - you should see a "Attack attempted" message. This is because a new token got generated on form submit and it doesn't match with the one in the session's data.

0
Subscribe to my newsletter

Read articles from Anjanesh Lekshminarayanan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anjanesh Lekshminarayanan
Anjanesh Lekshminarayanan

I am a web developer from Navi Mumbai working as a consultant for cloudxchange.io. Mainly dealt with LAMP stack, now into Django and trying to learn Laravel and Google Cloud. TensorFlow in the near future. Founder of nerul.in