Skip to main content

Double Submit Cookie Patterns πŸͺ πŸͺ to prevent Cross-site Request Forgery (CSRF)

What is CSRF - Cross Site Request Forgery 

When an unwanted action is forced to perform on a trusted site which the user is currently authenticated to , it's called a CSRF.


What is a double submit cookie pattern and how it works

Basically, there are are two patterns for stopping CSRF attacks: Double-Submit Cookie and Synchronizer Token. Lets see how Double Submit Cookie Pattern works!

It works like this. If a view is protected against CSRF, when the view responds to any petition whose request method is “unsafe”, e.g. POST, PUT, and DELETE, it requires a csrfmiddlewaretoken to be passed in the request payload. It checks the value of this token against the csrftoken, a cookie which is also passed along with the request. If they don’t have the same value, the request is rejected.

The key here is that the browser passes two tokens in the request which must have the same value. The csrfmiddlewaretoken, in the request body, and the csrftoken in the cookie.

When you log in, the csrftoken cookie on your browser resets to a random, unguessable string, and for the remainder of your session it renders forms with this token in a hidden input. The token is unique per user and per session.
An attacker site using JS to POST some status on your behalf can set any csrfmiddlewaretoken in the request payload, but it has no way of making this match with the csrftoken cookie that is also passed along with the request.


How to implement

Now you must have an idea about CSRF token and how an attacker can perform such malicious attacks. And this post will illustrate how you can implement csrf protection in web applications via double submit cookie method. I created a simple PHP login form and implemented csrf protection.


First thing is starting session from client side and also generating the CSRF token. Then you have to set cookies for the session id as well as for the csrf token. All these are done at the client side.

<?php
  session_start();


//storing session id

$sessionID=session_id();


//generate CSRF token

if(empty($_SESSION['key']))  // creating the session key for csrf token

{

$_SESSION['key']=md5(uniqid(mt_rand(),true));    

}


$csrf = hash_hmac('sha256',$sessionID,$_SESSION['key']);  
        //creating csrf token
$_SESSION['csrf']= $csrf;  // and storin it in session
setcookie("session_id",$sessionID,time()+3600,"/","localhost",false,true);  
        //setting a cookie for session id
setcookie("csrf",$csrf,time()+3600,"/","localhost",false,true); 
        //setting a cookie for csrf token 
?>

Then create your html login form including a DOM hidden field and then assign the csrf token to the hidden variable.
DOM Hidden field
<input type= "hidden" id="cs" name="csrf"/> //DOM hidden field creation
Assigning csrf token to the hidden varible
<script> document.getElementById("cs").value = '<?php echo $csrf; ?>' </script> 
And then validate the user .

<?php

//Session start 
session_start();
// if the user clicked the login button
if(isset($_POST['login']))
{
ob_end_clean();
//user and token validation
if($_POST['email']=="don.manula@gmail.com" && $_POST['password']=="manula" && $_POST['csrf']== $_COOKIE['csrf'] && $_COOKIE['session_id']==session_id())
{
echo "<script> alert('Login Sucess') </script>";
// this is if the user selected the remember me checkbox
if(isset($_POST['remember']))
{
setcookie('email',$_email,time()+60*60*7);  
                                        // set a cookie for email
setcookie('password',$_password,time()+60*60*7);
                                        // set a cookie for password
}
$_SESSION['email']=$_POST['email'];
echo "Welcome   "   .$_SESSION['email'];
echo "<a href='logout.php'> Logout</a>";
}
else
{
echo "<script> alert('Login Failed') </script>";
echo "Login Failed and Authorization Failed :(";
}
}
Related image

Comments