Gathering detailed insights and metrics for @fastify/csrf-protection
Gathering detailed insights and metrics for @fastify/csrf-protection
Gathering detailed insights and metrics for @fastify/csrf-protection
Gathering detailed insights and metrics for @fastify/csrf-protection
csrf-csrf
A utility package to help implement stateless CSRF protection using the Double Submit Cookie Pattern in express.
@fastify/csrf
primary logic behind csrf tokens
csrf-sync
A utility package to help implement stateful CSRF protection using the Synchroniser Token Pattern in express.
@fastify/busboy
A streaming parser for HTML form data for node.js
npm install @fastify/csrf-protection
94
Supply Chain
100
Quality
86
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
153 Stars
219 Commits
19 Forks
17 Watching
5 Branches
35 Contributors
Updated on 17 Nov 2024
Minified
Minified + Gzipped
JavaScript (89.1%)
TypeScript (10.9%)
Cumulative downloads
Total Downloads
Last day
-13.6%
2,565
Compared to previous day
Last week
2.7%
16,011
Compared to previous week
Last month
-7.3%
68,271
Compared to previous month
Last year
115.4%
824,733
Compared to previous year
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.
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-protection 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, performance, 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.
1npm i @fastify/csrf-protection
@fastify/cookie
If you use @fastify/csrf-protection
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 cookie options. Make sure you restore any of the default options which provide sensible and secure defaults.
1fastify.register(require('@fastify/cookie')) 2fastify.register(require('@fastify/csrf-protection')) 3 4// if you want to sign cookies: 5fastify.register(require('@fastify/cookie'), { secret }) // See following section to ensure security 6fastify.register(require('@fastify/csrf-protection'), { cookieOpts: { signed: true } }) 7 8// generate a token 9fastify.route({ 10 method: 'GET', 11 path: '/', 12 handler: async (req, reply) => { 13 const token = reply.generateCsrf() 14 return { token } 15 } 16}) 17 18// protect a route 19fastify.route({ 20 method: 'POST', 21 path: '/', 22 onRequest: fastify.csrfProtection, 23 handler: async (req, reply) => { 24 return req.body 25 } 26})
@fastify/session
If you use @fastify/csrf-protection
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.
1fastify.register(require('@fastify-session'), { secret: "a string which is longer than 32 characters" }) 2fastify.register(require('@fastify/csrf-protection'), { sessionPlugin: '@fastify/session' }) 3 4// generate a token 5fastify.route({ 6 method: 'GET', 7 path: '/', 8 handler: async (req, reply) => { 9 const token = reply.generateCsrf() 10 return { token } 11 } 12}) 13 14// protect a route 15fastify.route({ 16 method: 'POST', 17 path: '/', 18 onRequest: fastify.csrfProtection, 19 handler: async (req, reply) => { 20 return req.body 21 } 22})
@fastify/secure-session
If you use @fastify/csrf-protection
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.
1fastify.register(require('@fastify/secure-session'), { secret: "a string which is longer than 32 characters" }) 2fastify.register(require('@fastify/csrf-protection'), { sessionPlugin: '@fastify/secure-session' }) 3 4// generate a token 5fastify.route({ 6 method: 'GET', 7 path: '/', 8 handler: async (req, reply) => { 9 const token = reply.generateCsrf() 10 return { token } 11 } 12}) 13 14// protect a route 15fastify.route({ 16 method: 'POST', 17 path: '/', 18 onRequest: fastify.csrfProtection, 19 handler: async (req, reply) => { 20 return req.body 21 } 22})
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:
.env
files or anywhere in the repositoryApart 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 attacks etc.
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 @fastify/csrf. |
reply.generateCsrf([opts])
Generates a secret (if it is not already present) and returns a promise that resolves to the associated secret.
1const token = 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.
The option csrfOpts.hmacKey
is required if getUserInfo
has been specified in the module option in combination with using @fastify/cookie as sessionPlugin
fastify.csrfProtection(request, reply, next)
A hook that you can use for protecting routes or entire plugins from CSRF attacks.
Generally, we recommend using an onRequest
hook, but if you are sending the token
via the request body, then you must use a preValidation
or preHandler
hook.
1// protect the fastify instance 2fastify.addHook('onRequest', fastify.csrfProtection) 3 4// protect a single route 5fastify.route({ 6 method: 'POST', 7 path: '/', 8 onRequest: fastify.csrfProtection, 9 handler: async (req, reply) => { 10 return req.body 11 } 12})
You can configure the function to read the CSRF token via the getToken
option, by default the following is used:
1function getToken (req) { 2 return (req.body && req.body._csrf) || 3 req.headers['csrf-token'] || 4 req.headers['xsrf-token'] || 5 req.headers['x-csrf-token'] || 6 req.headers['x-xsrf-token'] 7}
It is recommended to provide a custom getToken
function for performance and security reasons.
1fastify.register(require('@fastify/csrf-protection'), 2 { getToken: function (req) { return req.headers['csrf-token'] } } 3)
or
1fastify.register(require('@fastify/csrf-protection'), 2 { getToken: (req) => req.headers['csrf-token'] } 3)
The latest stable version of the package.
Stable Version
2
5.3/10
Summary
Bypass of CSRF protection in the presence of predictable userInfo
Affected Versions
>= 5.0.0, < 6.3.0
Patched Versions
6.3.0
5.3/10
Summary
Bypass of CSRF protection in the presence of predictable userInfo
Affected Versions
< 4.1.0
Patched Versions
4.1.0
No security vulnerabilities found.