How @fastify/helmet works
mainhelmet library. It adds an 'onRequest' hook and a reply.helmet decorator to Fastify. It accepts the same configuration options as the standard helmet package.repository·main·Indexed 19 days ago
https://github.com/fastify/fastify-helmetA security plugin for Fastify that wraps the helmet library to provide essential security headers. It supports global or route-specific application, a reply.helmet decorator, and Fastify-specific features such as automatic Content-Security-Policy (CSP) nonce generation via the enableCSPNonces option.
helmet library. It adds an 'onRequest' hook and a reply.helmet decorator to Fastify. It accepts the same configuration options as the standard helmet package.Install the plugin using npm:
npm i @fastify/helmetBy default, @fastify/helmet is applied to all routes (global: true). You can disable this global application by passing { global: false } during registration, which allows you to enable it manually on specific routes or via the reply.helmet decorator.
// enable @fastify/helmet globally (default behavior)
fastify.register(helmet)
// or
fastify.register(helmet, { global: true })
// disable @fastify/helmet globally
fastify.register(helmet, { global: false })When enableCSPNonces: true is set in the plugin registration, @fastify/helmet generates unique nonces for scripts and styles for every request. These nonces are attached to the reply object.
To use them, access reply.cspNonce. The plugin automatically injects these nonces into the script-src and style-src directives of your Content Security Policy.
Note: For nonces to work, you must have the contentSecurityPolicy directive configured in your helmet options.
// 1. Register with nonces enabled
fastify.register(fastifyHelmet, {
enableCSPNonces: true
})
// 2. Access nonces in your route handler
fastify.get('/page', async (request, reply) => {
const { script, style } = reply.cspNonce
// Use the nonces in your HTML response
reply.type('text/html')
reply.send(`
<html>
<head>
<style nonce="${style}">body { background: red; }</style>
</head>
<body>
<script nonce="${script}">console.log('hello');</script>
</body>
</html>
`)
})By default, helmet includes a standard set of CSP directives. To provide your own entirely custom set of directives without the defaults, set useDefaults: false within the contentSecurityPolicy configuration object.
fastify.register(
helmet,
{
contentSecurityPolicy: {
useDefaults: false,
directives: {
'default-src': ["'self'"]
}
}
}
)Register @fastify/helmet to automatically add security headers to your Fastify application. By default, it applies a global configuration to all routes. You can control whether the plugin is applied globally using the global option and configure Content Security Policy (CSP) nonces using enableCSPNonces.
Available configuration options are passed directly to the underlying helmet package, with the exception of the plugin-specific enableCSPNonces and global keys.
const fastify = require('fastify')()
const fastifyHelmet = require('@fastify/helmet')
fastify.register(fastifyHelmet, {
// Plugin-specific options
enableCSPNonces: true,
global: true,
// Underlying helmet options
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"]
}
}
})Register the plugin to set basic security headers. You can pass options to customize or disable specific directives (e.g., contentSecurityPolicy: false).
const fastify = require('fastify')()
const helmet = require('@fastify/helmet')
fastify.register(
helmet,
// Example disables the `contentSecurityPolicy` middleware but keeps the rest.
{ contentSecurityPolicy: false }
)
fastify.listen({ port: 3000 }, err => {
if (err) throw err
})When global: false is set, or even when global: true is set, you can use the helmet shorthand option in route configuration to control security headers for specific endpoints:
{ helmet: false }.{ helmet: { frameguard: false } }.// register the package with the { global: true } option
fastify.register(helmet, { global: true })
fastify.get('/route-with-disabled-helmet', { helmet: false }, async (request, reply) => {
return { message: 'helmet is not enabled here' }
})
fastify.get('/route-with-custom-helmet-configuration', {
helmet: {
enableCSPNonces: true,
contentSecurityPolicy: {
directives: {
'directive-1': ['foo', 'bar']
}
}
}
}, async (request, reply) => {
return { message: 'helmet is enabled with a custom configuration on this route' }
})You can enable automatic CSP nonce generation by passing { enableCSPNonces: true } in the plugin options. The generated nonces are then available on the reply.cspNonce object.
Note: This feature is implemented by @fastify/helmet and is not a native feature of the underlying helmet library.
fastify.register(
helmet,
// enable csp nonces generation with default content-security-policy option
{ enableCSPNonces: true }
)
fastify.get('/', function(request, reply) {
// retrieve script nonce
reply.cspNonce.script
// retrieve style nonce
reply.cspNonce.style
})If helmet is not applied globally, you can use the reply.helmet() decorator inside your route handler to apply security headers conditionally.
fastify.get('/here-we-use-helmet-reply-decorator', async (request, reply) => {
if (condition) {
// we apply the default options
await reply.helmet()
} else {
// we apply customized options
await reply.helmet({ frameguard: false })
}
return {
message: 'we use the helmet reply decorator to conditionally apply helmet middlewares'
}
})Ensure your Fastify version is compatible with the plugin version you are using:
| Plugin version | Fastify version |
|---|---|
>=12.x | ^5.x |
>=9.x <12.x | ^4.x |
>=7.x <9.x | ^3.x |
>=1.x <7.x | ^2.x |
>=1.x <7.x | ^1.x |
The plugin decorates the Fastify reply object with two properties:
reply.cspNonce: An object containing { script, style } strings (hex-encoded random bytes) used for CSP nonces. This is only available if enableCSPNonces: true was passed during registration.reply.helmet(opts?): A function that allows you to manually trigger the helmet header application for the current request with optional overrides. If opts is provided, it is merged with the existing configuration.// Accessing nonces
const nonce = reply.cspNonce.script
// Manually applying helmet with overrides
await reply.helmet({ someHelmetOption: true })