Introduction

Before anything else, if you don't know what a CSRF attack really is, I advise you to read this great article on OWASP about Cross-Site Request Forgeries.

Now that you are familiar with the concept of CSRF and token protection, I'm sure you will find this class useful.

Download

Usage

NoCSRF::generate( $key )
CSRF token generation method. Returns a new base64-encoded token. After generating the token, put it inside a hidden form field named $key.

  • Parameter $key(String) The session key where the token will be stored. (Will also be the name of the hidden field name)
  • Return (String) The generated, base64 encoded token.

NoCSRF::check( $key, $origin[, $throwException[, $timespan[, $multiple]]] )
Check CSRF tokens match between session and $origin. Make sure you generated a token in the form before checking it.

  • Parameter $key(String) The session and $origin key where to find the token.
  • Parameter $origin(Mixed) The object/associative array to retreive the token data from (usually $_POST).
  • Parameter $throwException(Boolean) [Facultative] TRUE to throw exception on check fail, FALSE or default to return a boolean.
  • Parameter $timespan(Integer) [Facultative] Makes the token expire after $timespan seconds. (default = never)
  • Parameter $multiple(Boolean) [Facultative] Makes the token reusable and not one-time. (Useful for ajax-heavy requests).
  • Return (Boolean) If $thowException is set to false This method returns true if the check is successful, false if an attack is detected.

Example

Let's take an example. Create a new php script called 'test.php' and put the 'nocsrf.php' class inside the same folder.

First, you have to activate sessions and include the anti-CSRF class.

// Tokens are stored in session so you have to initialize session data
session_start();
// Then include the NoCSRF class
require_once('nocsrf.php');

Then use the NoCSRF::generate() method to generate the token for the specified field.

// Generate CSRF token to use in form hidden field
$token = NoCSRF::generate( 'csrf_token' );

And finally put this token in a hidden field of your form.

<form name="csrf_form" action="#" method="post">
	<input type="hidden" name="csrf_token" value="<?php echo $token; ?>">
	...Other form inputs...
    <input type="submit" value="Send form">
</form>

Now that you have the client side token generation written, all you have to do to check the token validity is use the NoCSRF::check() method before parsing your form's inputs.

try
{
	// Run CSRF check, on POST data, in exception mode, with a validity of 10 minutes, in one-time mode.
	NoCSRF::check( 'csrf_token', $_POST, true, 60*10, false );
	// form parsing, DB inserts, etc.
}
catch ( Exception $e )
{
	// CSRF attack detected
}

Links