npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fastify-csrf

v3.1.0

Published

A plugin for adding CSRF protection to Fastify.

Downloads

5,152

Readme

fastify-csrf

CI NPM version Known Vulnerabilities js-standard-style

This plugin helps developers protect their Fastify server against CSRF attacks. In order to fully protect against CSRF, developers should study Cross-Site Request Forgery Prevention Cheat Sheet in depth. See also pillarjs/understanding-csrf as a good guide.

Security Disclaimer

Securing applications against CSRF is a developer responsibility and it should not be fully trusted to any third party modules. We do not claim that this module is able to protect an application without a clear study of CSRF, its impact and the needed mitigations. fastify-csrf provides a series of utilities that developers can use to secure their application. We recommend using fastify-helmet to implement some of those mitigations.

Security is always a tradeoff between risk mitigation, functionality, and developer experience. As a result we will not consider a report of a plugin default configuration option as security vulnerability that might be unsafe in certain scenarios as long as this module provides a way to provide full mitigation through configuration.

Install

npm i fastify-csrf

Usage

Use with fastify-cookie

If you use fastify-csrf with fastify-cookie, the CSRF secret will be added to the response cookies. By default, the cookie used will be named _csrf, but you can rename it via the cookieKey option. When cookieOpts are provided, they override the default options. Make sure you restore any of the default options which provide sensible and secure defaults.

fastify.register(require('fastify-cookie'))
fastify.register(require('fastify-csrf'))

// if you want to sign cookies:
fastify.register(require('fastify-cookie'), { secret }) // See following section to ensure security
fastify.register(require('fastify-csrf'), { cookieOpts: { signed: true } })

// generate a token
fastify.route({
  method: 'GET',
  path: '/',
  handler: async (req, reply) => {
    const token = await reply.generateCsrf()
    return { token }
  }
})

// protect a route
fastify.route({
  method: 'POST',
  path: '/',
  onRequest: fastify.csrfProtection,
  handler: async (req, reply) => {
    return req.body
  }
})

Use with fastify-session

If you use fastify-csrf with fastify-session, the CSRF secret will be added to the session. By default, the key used will be named _csrf, but you can rename it via the sessionKey option.

fastify.register(require('fastify-session'))
fastify.register(require('fastify-csrf'), { sessionPlugin: 'fastify-session' })

// generate a token
fastify.route({
  method: 'GET',
  path: '/',
  handler: async (req, reply) => {
    const token = await reply.generateCsrf()
    return { token }
  }
})

// protect a route
fastify.route({
  method: 'POST',
  path: '/',
  onRequest: fastify.csrfProtection,
  handler: async (req, reply) => {
    return req.body
  }
})

Use with fastify-secure-session

If you use fastify-csrf with fastify-secure-session, the CSRF secret will be added to the session. By default, the key used will be named _csrf, but you can rename it via the sessionKey option.

fastify.register(require('fastify-secure-session'))
fastify.register(require('fastify-csrf'), { sessionPlugin: 'fastify-secure-session' })

// generate a token
fastify.route({
  method: 'GET',
  path: '/',
  handler: async (req, reply) => {
    const token = await reply.generateCsrf()
    return { token }
  }
})

// protect a route
fastify.route({
  method: 'POST',
  path: '/',
  onRequest: fastify.csrfProtection,
  handler: async (req, reply) => {
    return req.body
  }
})

Securing the secret

The secret shown in the code above is strictly just an example. In all cases, you would need to make sure that the secret is:

  • Never hard-coded in the code or .env files or anywhere in the repository
  • Stored in some external services like KMS, Vault or something similar
  • Read at run-time and supplied in this option
  • Of significant character length to provide adequate entropy
  • Truly random sequence of characters (You could use crypto-random-string)

Apart from these safeguards, it is extremely important to use HTTPS for your website/app to avoid a bunch of other potential security issues like MITM etc.

API

Module Options

| Options | Description | | ----------- | ----------- | | cookieKey | The name of the cookie where the CSRF secret will be stored, default _csrf. | | cookieOpts | The cookie serialization options. See fastify-cookie. | | sessionKey | The key where to store the CSRF secret in the session. | | getToken | A sync function to get the CSRF secret from the request. | | getUserInfo | A sync function to get the a string of user-specific information to prevent cookie tossing. | | sessionPlugin | The session plugin that you are using (if applicable). | | csrfOpts | The csrf options. See csrf. |

reply.generateCsrf([opts])

Generates a secret (if is not already present) and returns a promise that resolves to the associated secret.

const token = await reply.generateCsrf()

You can also pass the cookie serialization options to the function.

The option userInfo is required if getUserInfo has been specified in the module option. The provided userInfo is hashed inside the csrf token and it is not directly exposed. This option is needed to protect against cookie tossing.

fastify.csrfProtection(request, reply, next)

A hook that you can use for protecting routes or entire plugins from CSRF attacks. Generally, we recommend to use the onRequest hook, but if you are sending the token via the body, then you should use preValidation or preHandler.

// protect the entire plugin
fastify.addHook('onRequest', fastify.csrfProtection)

// protect a single route
fastify.route({
  method: 'POST',
  path: '/',
  onRequest: fastify.csrfProtection,
  handler: async (req, reply) => {
    return req.body
  }
})

You can configure the function to read the CSRF token via the getToken option, by default the following is used:

function getToken (req) {
  return (req.body && req.body._csrf) ||
    req.headers['csrf-token'] ||
    req.headers['xsrf-token'] ||
    req.headers['x-csrf-token'] ||
    req.headers['x-xsrf-token']
}

License

MIT