PHP Web Development

How to prevent Cross-Site Request Forgery (CSRF) in PHP

A cross-site request forgery (CSRF) vulnerability occurs when:
A web application uses session cookies.
he application acts on an HTTP request without verifying that the request was made with the user’s consent.

If the request does not contain a nonce that proves its provenance, the code that handles the request is vulnerable to a CSRF attack (unless it does not change the state of the application.)  This means a web application that uses session cookies has to take special precautions in order to ensure that an attacker can’t trick users into submitting bogus requests.

For more details visit–  https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

Implementation—-

Generating CSRF Token

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

bin2hex(random_bytes(32)) —Generates cryptographically secure pseudo-random bytes.

string random_bytes ( int $length )

Generates an arbitrary length string of cryptographic random bytes that are suitable for cryptographic use, such as when generating salts, keys or initialization vectors.

Verifying CSRF Token—-

if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) {
// Proceed to process the form data
} else {
// Log this as a warning and keep an eye on these attempts
}
}

Here is the full code —-

<?php 
session_start();
include('config.php'); // database Configuration file
//Genrating CSRF Token
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
if(isset($_POST['submit']))
{
//Verifying CSRF Token
if (!empty($_POST['csrftoken'])) {
if (hash_equals($_SESSION['token'], $_POST['csrftoken'])) {
$name=$_POST['name'];
$subject=$_POST['subject'];
$message=$_POST['message'];
$query=mysqli_query($con,"insert into tblcsrf (Name,Subject,Message) values('$name','$subject','$message')");
//if query run successfully
if($query)
{
echo '<script> alert("Record inserted successfully");</script>';
unset( $_SESSION['token']); // unset session token after submiiting
}
// If query not run
else
{
echo '<script> alert("Something went wrong. please try again."");</script>';   
}
} 
// if record already inserted
else {
echo '<script> alert("Record already inserted. Please fresh browser then try");</script>';   
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Fixing CSRF vulnerability in PHP Applications </title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
.red{
color:red;
}
.form-area
{
background-color: #FAFAFA;
padding: 10px 40px 60px;
margin: 10px 0px 60px;
border: 1px solid GREY;
}
</style>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" align="center">
<div class="col-md-7">
<div class="form-area">  
<form name="csrftoken" method="post">
<br style="clear:both">
<h3 style="margin-bottom: 25px; text-align: center;">How to implement CSRF token in php</h3>
<div class="form-group">
<input type="text" class="form-control" id="name" name="name" placeholder="Name" required>
</div>
<div class="form-group">
<input type="text" class="form-control" id="subject" name="subject" placeholder="Subject" required>
</div>
<div class="form-group">
<textarea class="form-control" type="textarea" id="message" name="message" placeholder="Message" maxlength="140" rows="7"></textarea>
<span class="help-block"><p id="characterLeft" class="help-block ">You have reached the limit</p></span>                    
</div>
<input type="hidden" name="csrftoken" value="<?php echo htmlentities($_SESSION['token']); ?>" /> 
<button type="submit" id="submit" name="submit" class="btn btn-primary pull-right">Submit Form</button>
</form>
</div>
</div>
</div>
<
<script type="text/javascript">
$(document).ready(function(){ 
$('#characterLeft').text('140 characters left');
$('#message').keydown(function () {
var max = 140;
var len = $(this).val().length;
if (len >= max) {
$('#characterLeft').text('You have reached the limit');
$('#characterLeft').addClass('red');
$('#btnSubmit').addClass('disabled');            
} 
else {
var ch = max - len;
$('#characterLeft').text(ch + ' characters left');
$('#btnSubmit').removeClass('disabled');
$('#characterLeft').removeClass('red');            
}
});    
});
</script>
</body>
</html>

How to run  the script

1. Download and Unzip file on your local system.
2. Put this file inside root directory
3. Database Configuration

open browser type http://localhost/phpmyadmin
Create a database demos.
Import database tblcsrf.sql
Open Your browser put inside browser “http://localhost/csrf/”

Download Source Code(How to prevent Cross-Site Request Forgery (CSRF) in PHP)
Size: 2.88 KB
Version: V 1.0

About the author

Anuj kumar

I'm Anuj kumar a web developer with 4+ year experience .I write blogs in my free time. I love to learn new technologies and share with others. I founded PHPGurukul in September 2015. The main aim of this website to is provide php , jquery , mysql , phpoops and other web development tutorials. I am trying best effort to make PHPGurukul useful for every single moment spend on this website. If you think this website is useful to visit please share with your friend and buddies.

Leave a Comment