What is 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. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.refer : https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) for more
How do we protect?
In this tutorial what we are going to do is , in brief we generate csrf token for the forms to send/receive requests from the server. Generated token should be synchronized/validated to get access to the server.
Assume that we have two sides such as client side (index.php) and server side (server.php).
Firstly, Start with a client (index.php) create a session and store it in a cookie. And also design the login form as given. (*hidden input in form will store value of token)
index.php
now we set the "sessionID" to the cookie named "user_login" and it will expire after 1 hour.
At the same time we need to start session on server side and create keyed hash value for csrf token. therefore,
server.php
After that we have to get token from client side (index.php) to fetch it with server side. So that I run AJAX callback function loadDoc() to send session id as token. (AJAX call : https://www.w3schools.com/xml/ajax_intro.asp)
loadDoc() Function JavaScript
calling loadDoc() in client Side (Index.php)
Now token has sent to the server side via ajax call. Finally, I implemented authorization part (through function "validate") which validates csrf token value and other input details whenever user clicks the submit button.
server.php
After the successfull login, it will show server page otherwise , it will be redirected to the client page (index.php).
Assume that we have two sides such as client side (index.php) and server side (server.php).
Firstly, Start with a client (index.php) create a session and store it in a cookie. And also design the login form as given. (*hidden input in form will store value of token)
index.php
<?php
session_start();
$sessionID = session_id(); //storing session id
setcookie("user_login",$sessionID,time()+3600,"/","localhost",false,true); //cookie terminates after 1 hour
?>
<form action="server.php" method="POST">
<input name="user" placeholder="Username" required="required" type="text" />
<input name="pass" placeholder="Password" required="required" type="password" />
<input id="IdOfToken" name="user_csrf" type="hidden" />
<button class="btn btn-primary btn-block btn-large" name="submit" type="submit">Let me in.</button>
</form>
now we set the "sessionID" to the cookie named "user_login" and it will expire after 1 hour.
At the same time we need to start session on server side and create keyed hash value for csrf token. therefore,
server.php
<?php
session_start(); //server session starts
generateToken(); //create and store token in to a session array
//create csrf token
function generateToken(){
if(empty($_SESSION['key']))
{
$_SESSION['key']=bin2hex(random_bytes(32));
}
$token = hash_hmac('sha256',"token for user login",$_SESSION['key']);
$_SESSION['CSRF_TOKEN'] = $token;
ob_start(); //store in buffer
}
Here we have created CSRF token and stored in server side session array named "CSRF_TOKEN" and also stored in buffer memory.After that we have to get token from client side (index.php) to fetch it with server side. So that I run AJAX callback function loadDoc() to send session id as token. (AJAX call : https://www.w3schools.com/xml/ajax_intro.asp)
loadDoc() Function JavaScript
function loadDOC(method,url,htmlTag)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if(this.readyState==4 && this.status==200)
{
document.getElementById(htmlTag).value = this.responseText;
}
};
xhttp.open(method,url,true);
xhttp.send();
}
calling loadDoc() in client Side (Index.php)
<?php
//ajax call
if(isset($_COOKIE['user_login']))
{
echo '<script> var token = loadDOC("POST","server.php","IdOfToken"); </script>';
}
?>
Now token has sent to the server side via ajax call. Finally, I implemented authorization part (through function "validate") which validates csrf token value and other input details whenever user clicks the submit button.
server.php
if(isset($_POST['submit']))
{
ob_end_clean(); //clean outer buffer memory
validate($_POST['user'],$_POST['pass'],$_POST['user_csrf'],$_COOKIE['user_login']);
}
function validate($username, $password,$user_token,$user_sessionCookie)
{
if($username=="admin" && $password=="admin")
{
if($user_token==$_SESSION['CSRF_TOKEN'] && $user_sessionCookie==session_id())
{
echo "<script> alert('Logged in Successfully') </script>";
echo "<h1 style=\"font-size:50px;text-align:center;\">Welcome : ".$username."<br/></h1>";
}
else
{
echo "<script> alert('Login failed! CSRFToken not matching!!') </script>";
echo "<script type=\"text/javascript\"> window.location.href = 'index.php'; </script>";
}
}
else{
echo "<script> alert('Login failed! Check your username, password and login again!!') </script>";
echo "<script javascript="" text="" type="\"> window.location.href = 'index.php'; </script>";
}
}
validate function i check the username, password and after that I compare "user_csrf" token from hidden input field to the token "CSRF_TOKEN" which we created at the beginning and checked sessionId in both which stored in cookie.After the successfull login, it will show server page otherwise , it will be redirected to the client page (index.php).

0 comments:
Post a Comment