A fastify csrf plugin.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib throw error on invalid token Feb 3, 2019
test Removed Cookie dependency Jan 15, 2019
.gitignore basic _csrf cookie key check Jan 8, 2019
.travis.yml Update .travis.yml Jan 15, 2019
LICENSE Create LICENSE Jan 15, 2019
README.md Update README.md Jan 23, 2019
package.json

README.md

Build Status js-standard-style

fastify-csrf

A fastify csrf plugin. Requires fastify-cookie (for cookie based CSRF token validation) or fastify-session (for session based)

Install

npm i fastify-csrf

API

csrf(fastify, options, next)

csrf will decorate request with a csrfToken(). It will generate token for validating request.

options

cookie

cookie set to true will use cookie for storing _csrf secret in browser cookie.

 { cookie: true } 

key

 { cookie: true, key: '_csrf_custom' }

this will set cookie with a name _csrf_custom.

ignoreMethods

 { cookie: true, ignoreMethods: ['GET', 'HEAD', /* other request type */] }

ignoreMethods takes a array of request type to skip validation for particular request type. Other properties related to cookie can be set normally.

 { cookie: { path: '/', maxAge: /* your maxAge value */, expires: /* cookie expiry time */ ,/* other cookie properties */}}

Session based validation options For using session validation, skip cookie option and use other options according to your requirement.

 { key: 'your_secret_key_name', ignoreMethods: [/* request types */] }

fastify-csrf uses fastify-session for sessions. Thus any option support by fastify-session is also valid for fastify-csrf.

Usage

Cookie based token validation.

const fastify = require('fastify')();
const fastifyCookie = require('fastify-cookie');
const fastifyFormBody = require('fastify-formbody');
const fastifyCSRF = require('fastify-csrf');

fastify.register(fastifyCookie);
fastify.register(fastifyFormBody);
fastify.register(fastifyCSRF, { cookie: true });

fastify.get('/', (request, reply) => {
  var form = `
      <form method = "post" action="/data">
         <input type="text" name"field_name"/>
         <input type="hidden" value="${ request.csrfToken() }" 
	 name="_csrf /* this token can be sent in request header as well */"/>
         <button type="submit">Submit</button>
      </form>
    `;
   reply.type('text/html').send(form);
});

fastify.post('/data', (request, reply) => {
  reply.send('Post successful');
});

fastify.listen(3000, (err) => {
  if(err) {
    process.exit(0);
   }
})

fastify-csrf depends on fastify-cookie so require it first. Set { cookie: true } for setting a cookie defaults to '_csrf', for setting different name use { cookie: true, key: '_csrf_custom' }. Create a hidden field with name '_csrf' which will store token.

Session based token validation.

const fastify = require('fastify')();
const fastifyCookie = require('fastify-cookie');
const fastifyFormBody = require('fastify-formbody');
const fastifySession = require('fastify-session');
const RedisStore = require('connect-redis')(fastifySession);
const fastifyCSRF = require('fastify-csrf');

fastify.register(fastifyCookie);
fastify.register(fastifyFormBody);
fastify.register(fastifySession, { cookieName: '_ses', cookie: { path: '/',secure: false },  
secret: 'a secret with minimum length of 32 characters', store: new RedisStore(/* redis configurations */) });
fastify.register(fastifyCSRF, { key: '_csrf', ignoreMethods: ['GET', 'HEAD', 'OPTIONS'] });

fastify.get('/',(request, reply) => {
	var form = `
		<form method="post" action="/data">
			<input type="text" name="user"/>
			<input type="hidden" value ="${ request.csrfToken() }" 
			name="_csrf /* this token can be sent in request header as well */"/>
			<button type="submit">Submit </buttion>
		</form>
	`;
	reply.type('text/html').send(form);
});

fastify.post('/data',(request, reply) => {
 reply.send('Post successful');
});

fastify.listen(3000,(err) => {
	if(err) {
		process.exit(0);
	}
});

fastify-csrf will use redis to store csrf token with a name given in key (in this case its, _csrf, custom name can be given).

Token can be sent in request header. Token is read in following order.

  • request.body._csrf - typically generated by the body-parser module.
  • request.query._csrf - a built-in from Express.js to read from the URL query string.
  • request.headers['csrf-token'] - the CSRF-Token HTTP request header.
  • request.headers['xsrf-token'] - the XSRF-Token HTTP request header.
  • request.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header.
  • request.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header.

Note: fastify-csrf is inspired by expressjs/csurf. For any other detail please visit expessjs/csurf.