Mitigating CSRF Issues

Tags CSRF

Add CSRF Token to a Form

Note: If the form is self-submitting, please refer to the next section.

We will assume for this example that test.php is submitting a $_POST request to submit.php.

  1. First, generate a new token at the top of the test.php immediately after our session class is loaded in. This will ensure that every time the form loads it has a new token.
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
  1. Then, you'll want to add a hidden field to the form:
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
  1. Next, you'll need to check for a $_POST request on submit.php and verify that the token is correct.
// Validate CSRF token on $_POST request 
if ($_SERVER['REQUEST_METHOD'] === 'POST') {  
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { 
        die("Invalid CSRF token"); 
    }  
    // Process form submission 
    // Your code to handle form submission goes here 
} 
  1. Finally, you'll need to test this locally to ensure the CSRF vulnerability has been mitigated.

Add CSRF Token to Self-Submitting Form

A self-submitting form, meaning a PHP form page (ex: test.php) that submits a $_POST request to itself (ex: test.php).

  1. First, generate a new token on each page load that is not a $_POST request. This will ensure that every time the form loads it has a new token, but when a $_POST is being received it will not overwrite the previous token and instead read the token and verify it before any action is taken.
// Validate CSRF token on $_POST request
if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { 
        die("Invalid CSRF token"); 
    } 
    // Process form submission 
    // Your code to handle form submission goes here 
}

// If not $_POST request, then generate new CSRF token and store it in session
else {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
  1. Then, you'll want to add a hidden field to the form:
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
  1. Finally, you'll need to test this locally to ensure the CSRF vulnerability has been mitigated.