PHPGurukul

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

Anuj Kumar

This is Anuj Kumar. I’m a professional 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 provide PHP, Jquery, MySQL, PHP Oops and other web development tutorials.
.

Recommended Tutorials for you


2 comments

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.