How to Implement Custom CSRF Token in PHP


Implement Custom CSRF Token in PHP

Demo Download

In this tutorial, I will show you how to implement custom CSRF token in PHP.

CSRF stands for Cross-Site Request Forgery, it is a type of attack on application in which hacker submit form on another website from malicious site using HTML form action attribute.

This can delete your record from any website’s database or can access your database records, or even can transfer fund from your bank account to hacker account.

Example of Attack on Website Without CSRF Token:

Suppose, you are currently logged in to yourbank.com and visit the malicious-website.com for reading an interesting or trending article written by malicious website.

This malicious website submit the below hidden form to yourbank.com to transfer fund from your account to hacker’s account.

<form action="https://yourbank.com/transfer" method="POST">
  <input type="hidden" name="amount" value="100" />
  <input type="hidden" name="transfer_to" value="987654321" />
</form>
<script>
  document.forms[0].submit();
</script>

If yourbank.com has not implemented the CSRF token then the fund will be transferred from your account to hacker account.

CSRF token protection helps to prevent such attacks on your application.

CSRF token is just a random string that is created in your website session and also submitted via HTML form.

I will simply compare these two strings to ensure that the request is initiated from my own website.

If both strings are matched then the request is authentic otherwise request is invalid.

If somehow hacker manage to find out my CSRF token then hacker can access my website, therefore I will expire CSRF token after 30 minutes.

You can set the expire time as per your need, minimum time is better as if somehow my token is compromised, it will be useless after 30 minutes later.

Readers Also Read: Best VPN for Web Developers to enhance the security and data privacy.

Additionally, I will also delete CSRF token after the successful operation and creates a new one so that one token can not be used multiple times.

Alternate way to secure your application is automatically logout inactive user in PHP.

Steps to Implement Custom CSRF Token in PHP

  1. Generate a CSRF Token & Embed it in HTML Form
  2. Compare the Session CSRF Token with Form Submitted CSRF Token
  3. Add Some Style to the Form

1. Generate a CSRF Token & Embed it in HTML Form

Before generating a CSRF token, first start the PHP session at the top of the page. After that generate a random string and assign it to session variable.

Here is the code to generate a CSRF token in PHP.

Create a csrf_token.php file and paste the following code in it.

<?php
session_start();
$csrf_error = "";
if (empty($_SESSION['_token'])) {
    $_SESSION['_token'] = bin2hex(random_bytes(32));
	$_SESSION["token_expire"] = time() + 1800; // 30 minutes = 1800 secs
}

$token = $_SESSION['_token'];
$token_expire = $_SESSION["token_expire"];

Create an index.php file and paste the following code in it.

<?php
require("csrf_token.php");
$success = false;
if ($_SERVER["REQUEST_METHOD"] == "POST" && empty($csrf_error)) {
    // Implement your business logic here
    // If your validation and operation is successful
    // then set $success to true, unset token & token expire
    // $success = true;
    if($success){
        unset($_SESSION["_token"]);
        unset($_SESSION["token_expire"]);
    }
}
?>
<html>
<head>
<title>Implement Custom CSRF Token in PHP</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<?php
if(!empty($csrf_error)){
    echo "<div class='alert alert-danger'><h2>".$csrf_error."</h2></div>";
}
?>

<h2>Sample Login Form</h2>
<form action="" method="post">
    <label for="email">Email Address:</label>
    <input type="email" name="email" required>
    <label for="password">Password:</label>
    <input type="password" name="password" required>
    <input type="hidden" name="_token" value="<?php echo $token; ?>">
    <input type="submit" value="Login">
</form>
</body>
</html>

As you can see in the above HTML form, I have passed the $token in hidden input field named _token which will be submitted along with the form.

2. Compare the Session CSRF Token with Form Submitted CSRF Token

When the form is submitted, first I will check that token is not expired then I will compare both the session CSRF token with the form submitted token, if they both are same then the request is valid.

Add the following code in a csrf_token.php file to cross-check the submitted CSRF token against the session CSRF.

if ($_SERVER["REQUEST_METHOD"] == "POST") {
	if (isset($_POST["_token"]) && !empty($token) && !empty($token_expire)) {
		if (time() >= $token_expire) {
			$csrf_error = "Token is expired. Please reload the form.";
			unset($_SESSION["_token"]);
		}else{
			if (!hash_equals($token, $_POST['_token'])) {
				$csrf_error = "Invalid Token";
			}
		}
	}else{
		$csrf_error = "Invalid Token";
	}
}
?>

Although till now I have successfully implemented the CSRF token protection in PHP. But I would like style to my form.

3. Add Some Style to the Form

This will add some styles to my HTML form, simply create an style.css file and paste the following code in it.

body {
    font-family: 'Arial',sans-serif;
    line-height: 1.6;
}
label{
    font-weight: bold;
    display: block;
}
input[type='email'], input[type='password'] {
    width: 300px;
    border-radius: 2px;
    border: 1px solid #CCC;
    padding: 10px;
    color: #333;
    font-size: 14px;
    margin: 10px 0px;
    display: block;
}
input[type='submit'] {
    padding: 10px 25px 8px;
    color: #fff;
    background-color: #0067ab;
    text-shadow: rgba(0,0,0,0.24) 0 1px 0;
    font-size: 16px;
    box-shadow: rgba(255,255,255,0.24) 0 2px 0 0 inset, #fff 0 1px 0 0;
    border: 1px solid #0164a5;
    border-radius: 2px;
    margin-top: 15px;
    cursor: pointer;
}
input[type='submit']:hover {
    background-color: #024978;
}
.alert {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
}
.alert-danger {
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

Conclusion

I hope by now you know how to implement custom and simple CSRF token in PHP.

If you found this tutorial helpful, share it with your friends and developers group.

I spent several hours to create this tutorial, if you want to say thanks so like my page on Facebook, Twitter and share it.

Demo Download

Facebook Official Page: All PHP Tricks

Twitter Official Page: All PHP Tricks

Article By
Javed Ur Rehman is a passionate blogger and web developer, he loves to share web development tutorials and blogging tips. He usually writes about HTML, CSS, JavaScript, Jquery, Ajax, PHP and MySQL.

Leave a Reply

Your email address will not be published. Required fields are marked *