FastSitePHP\Security\Web\CsrfStateless

‘Stateless’ CSRF Tokens

Stateless CSRF Tokens are not stored in Session but rather use a crypto keyed-hash message authentication code (HMAC) to create and verify the token.

Stateless Tokens work well if authentication happens with cookies that do not use standard PHP session functions, that said this class also works well with PHP Sessions and provides expiration time that can be changed per page.

If stateless authentication always happens through Request Headers for POST Requests and other transactions then CSRF attacks are prevented and CSRF Tokens are not needed. CSRF Tokens are generally needed if authentication happens with cookies (by default Session code always uses cookies).

If using PHP 5.3 then using this class will polyfill functions [bin2hex()] and [hex2bin()] and if using a version of PHP below 5.6 then this class will polyfill [hash_equals()].

For another Stateless CSRF Token implementation with NodeJS see the link below.

Source Code

GitHub

Example Code

Security - Stateless CSRF

// Stateless CSRF Tokens are not stored in Session but rather use a crypto
// keyed-hash message authentication code (HMAC) to create and verify the token.

// A secure secret key is required.
// The key would typically be saved with your app or in config.
$key = \FastSitePHP\Security\Web\CsrfStateless::generateKey();

// To use the Key it must be saved to either a config value or
// an environment variable before calling [setup()].
$app->config['CSRF_KEY'] = $key;
// putenv("CSRF_KEY=${key}");

// A unique identifier for the user is also required. This doesn't have
// to be secret and can be a simple as an numeric field in a database.
$user_id = 1;

// Setup and validate stateless CSRF Tokens
\FastSitePHP\Security\Web\CsrfStateless::setup($app, $user_id);

// Optionally add a timeout, this CSRF token will expire after 5 minutes
$expire_time = '+5 minutes';
\FastSitePHP\Security\Web\CsrfStateless::setup($app, $user_id, $expire_time);

// The same logic is used when using the [CsrfSession] class so
// the token is assigned a locals value in the Application Object
// which allows for it to be used with templating code.
$token = $app->locals['csrf_token'];
//
// <meta name="X-CSRF-Token" content="{{ $csrf_token }}">
// <input name="X-CSRF-Token" value="{{ $csrf_token }}">

// Also just like [CsrfSession] a good place to call [setup()]
// is on route filter functions.
$csrf = function() use ($app, $user_id) {
    \FastSitePHP\Security\Web\CsrfStateless::setup($app, $user_id);
};

$app->get('/form', function() use ($app) {
    return $app->render('form.php');
})
->filter($csrf);

Methods

generateKey()

Static Function

Return a key that can be used to generate and validate Stateless CSRF Tokens. The key must be kept private and not shared with end users.

Returns: string

setup(Application $app, $user_id, $expire_time = null, $key = 'X-CSRF-Token')

Static Function

Setup and validate stateless CSRF Tokens. A good place to call this function is on route filters of pages that use authentication.

This will assign the token to app property $app->locals['csrf_token'] which then must be included with the form or response. When using [$app->render()] the value will be available as variable [$csrf_token].

This function requires the App config value $app->config['CSRF_KEY'] or an Environment Variable of the same name with a key generated from the function [generateKey()].

For usage see demo code.