# Using token in vanilla PHP for CSRF

Frameworks like Django and Laravel have [CSRF Protection](https://laravel.com/docs/11.x/csrf) 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](https://laracasts.com/series/30-days-to-learn-laravel-11/episodes/16).

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.

```bash
touch form.php
touch form-post.php
code .
```

**form.php**

```php-template
<?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-template
<?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>"
?>
```

```bash
php -S localhost:8004
```

Now browse to [http://localhost:8004/form.php](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.
