Monday, May 14, 2018

Cross-site Request Forgery protection in web applications via Synchronizer Token Patterns

What is CSRF(Cross-site Request Forgery)?

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. Little bit confusing right, watch the below video you will understand it fully.



What is Synchronizer Token Patterns? 

Synchronizer token pattern (STP) is a technique where a token, secret and unique value for each request, is embedded by the web application in all HTML forms and verified on the server side. The token may be generated by any method that ensures unpredictability and uniqueness.

Let's implement this using a simple example using PHP.

First, create a basic html form to login users. with Username field and password field.

<form action="login.php" method="POST" class="ajax" >
    <lable>Username:</lable>
    <input type="text" required name="uname" />
    <lable>Username:</lable>
    <input type="password" required name="password" />
     
    <input type="submit" value="Login"/>
<div id="success"></div>
</form

Then we need to create a cookie called "s_id" (later will use this to validate our form)  from php session which generates a unique value when you visit the website and once you close browser it will destroy the session.


<?php 
session_start();
$s_id = session_id();
setcookie("s_id",$s_id,time()+(1440),"/","localhost",false,true);
?>


Now the cookie is created in the browser, now we can generate a synchronizer token pattern simply a unique value for each request.


<?php 
    
       if (empty($_SESSION['token'])) {
       
            $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
      
        $token = $_SESSION['token'];
        
   }


In here I have used "bin2hex and openssl_random_pseudo_bytes" because "openssl_random_pseudo_bytes" is cryptographically secure and bin2hex convert binary data into hexadecimal representation. So that the token value will be unique each time.

Now we need to pass token value as POST method to login verification page. In order to do that we should assign the token into hidden field in the form as below.


<input type="hidden" name="csr" value="<?php echo $_SESSION['token']; ?>">


Finally, let's implement the login page with a ajax with jquery. We will be using a function that automatically gets values from the form and the action url and submits it using ajax as below.


<script>
 $('form.ajax').on('submit', function() {
    var that = $(this),
            url = that.attr('action'),
            type = that.attr('method'),
            data = {};
    that.find('[name]').each(function(index, value) {
        var that = $(this),
                name = that.attr('name'),
                value = that.val();
        data[name] = value;
    });
    $.ajax({
        url: url,
        type: type,
        data: data,
        success: function(response) {
            $("#success").append("<h3 style='color:red; font-size:15px;'>" + response + "</h3>");          
             
        }
    });
    return false;
});
 
 </script>

Login.php


<?php 
session_start();
$uname=$_POST['uname'];
$password=$_POST['password'];
$userSession=$_COOKIE['s_id'];
$csr=$_POST['csr'];
if(empty($uname) || empty($password)){
    echo "Please fill all the required fields\n";
}else{
    
    if($uname="admin" && $password="admin" && $userSession=session_id() && $csr=$_SESSION['token']){
        echo "Login successful, Hello admin";
    }else{
        echo "Login un-successful";
    }
}
?>

Download source code : https://github.com/theekshanasl/SSS/tree/master/Assignment%201









0 comments:

Post a Comment