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
1 2 3 4 5 6 |
<?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—-
1 2 3 4 5 6 7 |
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 —-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
<?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/”