Cross-Site Request Forgery (CSRF) is a web security vulnerability attack that occurs when a malicious website or program causes a user’s web browser to perform an unwanted action on a trusted site when the user is authenticated. The attack allows an attacker to induce users to perform actions that they do not intend to perform. In a successful CSRF attack, the attacker causes the victim user to carry out an action unintentionally.
Most web application frameworks have built-in CSRF features (i.e. Laravel CSRF https://laravel.com/docs/9.x/csrf). Below is an example where created an easy and simple way protect against CSRF.
index.php
<?php session_start(); //Generate CSRF token function csrf_token() { if (empty($_SESSION['csrf'])) { if (function_exists('random_bytes')) { $_SESSION['csrf'] = bin2hex(random_bytes(32)); } else if (function_exists('mcrypt_create_iv')) { $_SESSION['csrf'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); } else { $_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(32)); } } $token = $_SESSION['csrf']; return $token; } //Check CSRF data function check_csrf($token) { if(isset($token) && empty($token)) { echo '<div class="alert alert-warning m-2" role="alert"><b>Error:</b> Incorrect <abbr title="Cross Site Request Forgery">CSRF</abbr> token is missing.</div>'; header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed'); exit; } //if (!hash_equals($_SESSION['csrf'], $_POST['csrf'])) die(); elseif (!hash_equals($_SESSION['csrf'], $_POST['csrf'])) { // show an error message echo '<div class="alert alert-danger m-2" role="alert"><b>Error:</b> Incorrect <abbr title="Cross Site Request Forgery">CSRF</abbr> token.</div>'; // return 405 http status code header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed'); exit; } } //Sanitize user data function cleanInput($data) { $data = trim($data); $data = stripslashes($data); $data = addslashes($data); //$data = htmlspecialchars($data); return $data; } if(isset($_POST['submit'])) { //check CSRF check_csrf($_POST['csrf']); //Form data $sFirstName = cleanInput($_POST['sFirstName']); $sLastName = cleanInput($_POST['sLastName']); $sAddress1 = cleanInput($_POST['sAddress1']); $sAddress2 = cleanInput($_POST['sAddress2']); $sCity = cleanInput($_POST['sCity']); $sStateCode = cleanInput($_POST['sStateCode']); $sZipCode = cleanInput($_POST['sZipCode']); $sEmailAddress = cleanInput($_POST['sEmailAddress']); $dBirthDate = cleanInput($_POST['dBirthDate']); $bOptIn = cleanInput($_POST['bOptIn']); //Do insert, update, } ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://getbootstrap.com/docs/5.2/assets/css/docs.css" rel="stylesheet"> <title>CSRF Example</title> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"></script> </head> <body class="p-3 m-0 border-0 bd-example"> <!-- Example Code --> <form class="row g-3" action="" method="post"> <!-- hidden CSRF token --> <input type="hidden" class="form-control" id="csrf" name="csrf" placeholder="csrf" value="<?php echo csrf_token();?>"> <div class="col-md-6"> <label for="sFirstName" class="form-label">First Name</label> <input type="text" class="form-control" id="sFirstName" name="sFirstName"> </div> <div class="col-md-6"> <label for="sLastName" class="form-label">Last Name</label> <input type="text" class="form-control" id="sLastName" name="sLastName"> </div> <div class="col-12"> <label for="sAddress1" class="form-label">Address</label> <input type="text" class="form-control" id="sAddress1" placeholder="1234 Main St" name="sAddress1"> </div> <div class="col-12"> <label for="sAddress2" class="form-label">Address 2</label> <input type="text" class="form-control" id="sAddress2" placeholder="Apartment, studio, or floor" name="sAddress2"> </div> <div class="col-md-6"> <label for="sCity" class="form-label">City</label> <input type="text" class="form-control" id="sCity" name="sCity"> </div> <div class="col-md-4"> <label for="sStateCode" class="form-label">State</label> <select id="sStateCode" class="form-select"> <option selected="">Choose...</option> <option>...</option> </select> </div> <div class="col-md-2"> <label for="sZipCode" class="form-label">Zip</label> <input type="text" class="form-control" id="sZipCode" name="sZipCode"> </div> <div class="col-md-6"> <label for="sEmailAddress" class="form-label">Email</label> <input type="email" class="form-control" id="sEmailAddress" name="sEmailAddress"> </div> <div class="col-md-6"> <label for="dBirthDate" class="form-label">Date of Birth</label> <input type="date" class="form-control" id="dBirthDate" name="dBirthDate"> </div> <div class="col-12"> <div class="form-check"> <input class="form-check-input" type="checkbox" id="bOptIn" name="bOptIn"> <label class="form-check-label" for="gridCheck"> Check me out </label> </div> </div> <div class="col-12"> <button type="submit" class="btn btn-primary" name="submit" id="submit">Sign in</button> </div> </form> <!-- End Example Code --> </body> </html>
Hope it will help against CSRF attack.