GithubHelp home page GithubHelp logo

tzkmx / statelesscsrf Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ayesh/statelesscsrf

0.0 1.0 0.0 45 KB

Secret-key based state-less CSRF token generator and validator for PHP 7. State-less means you do not have to store the CSRF token in session or database.

License: MIT License

PHP 100.00%

statelesscsrf's Introduction

Stateless CSRF - Secret-key based Cross-Site-Request Forgery Protection tokens

Packagist license CI

ayesh/stateless-csrf is PHP library that generates and validates stateless CSRF-protection tokens. This means the generated tokens are not stored in a database or disk on the server. Instead, a combination of a secret key (that only the server knows) and clues to identify a browser are used.

Because we do not store the generated tokens, this library does not provide protection against replay attacks.

Requirements

  • PHP 7.4 or later.
  • PHP built-in extensions: Hash and JSON (available unless PHP is compiled manually without these extensions).

Features

  • Generate a secure token using SHA-256 HMAC.
  • Optionally set an expiration time to tokens.
  • Generated tokens are URL-safe.
  • Optimized to be used with an Inversion of Control container.
  • Token validation is time-attack safe.

Installation

Copy-pasta the following in your terminal:

composer require ayesh/stateless-csrf

Examples

Simple Example without variables

Before the library can generate tokens, it must be fed with a secret key. This key can be a string of any length, and is used as the key in HMAC operations.

<?php 

use Ayesh\StatelessCSRF\StatelessCSRF;

$csrf_generator = new StatelessCSRF('your-secret-key-here');
$token = $csrf_generator->getToken('unique-id-for-key');

$csrf_generator->validate('unique-id-for-key', $token);

Above is the simplest example. First, we initialize the CSRF token generator with a secret key (your-secret-key-here). Any StatelessCSRF instance instantiate with the same secret key will be able to valdiate tokens generated by the other.

In an ideal use case, you will not be doing things like this. This library is meant to be used with an IoC container. Generate a single StatelessCSRF instance, and use it to generate as many as tokens needed. In subsequent requests, new StatelessCSRF instances (which are generated with the same secret) will be able to valdiate them. See the example at the bottom of this README for more elaborate examples.

Example with token expiration.

Because this library does not provide replay attack protection, an expiration time for the tokens makes more sense. The expiration time of the token is provided at the time the is generated. In the getToken method, set the second parameter to the UNIX timestamp when the token should expire.

<?php 

use Ayesh\StatelessCSRF\StatelessCSRF;

$csrf_generator = new StatelessCSRF('your-secret-key-here');
$token = $csrf_generator->getToken('unique-id-for-key', time() + 3600); // Expires in an hour.

$csrf_generator->validate('unique-id-for-key', $token);

In the validate(), you can provide the current time as the third parameter. If not provided, the token expiration timestamp will be compared against the current system time (what time() returns).

The expiration time is signed, so an attacker cannot change the timestamp and bypass the expiration.

Juicy example with user-agent, IP address, etc validation.

Although a secret-key based token combined with an expiration time provides good protection, you can make things more strict with user-agent string and IP address validation. For the library, it just needs to be fed with same "glue" values at both generation and validation stages.

You can use any value that uniquely identifies a user. User-agent string provided by the user and peer IP address are two great examples.

<?php 

use Ayesh\StatelessCSRF\StatelessCSRF;

$csrf_generator = new StatelessCSRF('your-secret-key-here');
$csrf_generator->setGlueData('ip', $_SERVER['REMOTE_ADDR']);
$csrf_generator->setGlueData('user-agent', $_SERVER['HTTP_USER_AGENT']);

$token = $csrf_generator->getToken('unique-id-for-key', time() + 3600); // Expires in an hour.

$csrf_generator->validate('unique-id-for-key', $token);

In the snippet above, ip and user-agent are arbitrary values. You can add any number of glue values. Calling setGlueData on the same key twice will overwrite the old value.

In the validator instance, the same set of glue values must be set, and set in the same order. I intentionally left out the glue value sorting to encourage callers to use some sort of container to get the StatelessCSRF instance instead of creating one everytime a token needs to be validated.

Example with Slim PHP Framework

use Ayesh\StatelessCSRF\StatelessCSRF;

$container['csrf'] = static function (Container $container): StatelessCSRF {
	$settings = $container->get('settings');
	$csrf = new StatelessCSRF($settings['secret_key']);
	$request = $container->get('request');
	$csrf->setGlueData('user_agent', $request->getHeaderLine('user-agent'));

	$server = $request->getServerParams();
	$csrf->setGlueData('ip', $server['REMOTE_ADDR']);

	return $csrf;
};

Now, from the container, you can fetch the StatelessCSRF instance from $container['csrf'], and it will be ready to be used with getToken and validate() calls.

Contribute

Contributions are welcome. Please feel to open an issue and/or send PRs along. For PRs, I appreciate the appropritate test coverage as well.

statelesscsrf's People

Contributors

ayesh avatar nicolascarpi avatar peter279k avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.