Nuxt Security Module
The Nuxt Security module is a robust solution for enhancing the security posture of Nuxt 3 applications by automatically configuring HTTP headers and server middleware according to OWASP principles. It provides features such as Content Security Policy (CSP), HTTP Strict Transport Security (HSTS), X-XSS-Protection, Referrer-Policy, and Permissions-Policy, alongside runtime protections like request size and rate limiters, Cross-Site Scripting (XSS) validation, and Cross-Origin Resource Sharing (CORS) support. The module also offers optional features like basic authentication, allowed HTTP methods control, and CSRF protection. Currently stable at version 2.5.1, `nuxt-security` maintains a rapid release cycle, with frequent hotfixes and minor versions addressing issues, introducing new features, and keeping pace with Nuxt 3 updates. Its primary differentiator is the comprehensive, opinionated, and automatic application of common security best practices without extensive manual configuration. It focuses on server-side protections and integration with Nuxt's SSR/SSG capabilities.
Common errors
-
Cannot find module 'nuxt-security' or its corresponding type declarations.
cause The module is not installed, or it's not correctly added to the `modules` array in `nuxt.config.ts`, or the type declarations are not properly resolved.fixRun `npx nuxi@latest module add security` or `npm install nuxt-security` to ensure the package is installed. Verify that `'nuxt-security'` is present in the `modules` array within your `nuxt.config.ts`. -
Refused to load the script '<URL>' because it violates the following Content Security Policy directive: "script-src".
cause Your Content Security Policy (CSP) headers, configured by `nuxt-security`, are preventing a script from loading because its origin or attributes do not match the allowed directives.fixReview the `security.headers.contentSecurityPolicy` configuration in `nuxt.config.ts`. Add the problematic URL's domain to the `script-src` directive, or consider using `'unsafe-inline'`/`'unsafe-eval'` (with caution) or `nonce`/`hash` attributes if dynamic inline scripts are necessary. -
405 Method Not Allowed
cause The HTTP request used a method (e.g., PUT) that is not permitted for the specific route by the `security.allowedHTTPMethods` configuration.fixCheck the `security.allowedHTTPMethods` configuration in `nuxt.config.ts` for the route in question. Ensure that the HTTP method used by your client is included in the `value` array. Adjust the configuration or client request method as appropriate. -
429 Too Many Requests
cause The rate limiter middleware, configured via `security.rateLimiter`, has detected that too many requests originated from the same client within the defined interval.fixIncrease the `tokens` (maximum requests) or `interval` (time window) values in your `security.rateLimiter` configuration. Alternatively, if the client is legitimate and requires higher limits, consider adding its IP address to the `whiteList` option (if applicable). -
ERR_PNPM_PEER_DEP_ISSUES: Peer dependencies error (or similar npm/yarn error related to Node.js version)
cause Your Node.js environment does not meet the minimum version requirement (Node.js >=20.0.0) specified by `nuxt-security` since version 2.3.0.fixUpgrade your local and deployment Node.js version to 20 or higher. Use a Node Version Manager like `nvm` or `fnm` to manage different Node.js versions efficiently.
Warnings
- breaking The module upgraded its minimum Node.js version requirement to 20.0.0 in v2.3.0. Applications deployed with older Node.js versions will encounter runtime errors or fail to build.
- gotcha Prior to v2.1.2, `console.log` statements were removed in development mode by default if the `removeLoggers` option was implicitly or explicitly enabled, leading to unexpected debugging challenges. This behavior was changed in a hotfix.
- gotcha Incorrectly configured Content Security Policy (CSP) can severely restrict a web application, blocking legitimate scripts, styles, images, and other resources. This often results in a broken user interface or functionality, especially in SSR/SSG contexts where nonces or hashes might be required.
- gotcha The XSS validator can be overly aggressive and block legitimate user input, particularly in applications that handle rich text, HTML snippets, or other forms of complex data. This can lead to a poor user experience or data loss.
- gotcha Aggressive rate limiting configurations can unexpectedly block legitimate API clients, bots, or integrations, leading to service disruption or inaccessible features. This is particularly problematic for applications with diverse client bases or sudden spikes in legitimate traffic.
Install
-
npm install nuxt-security -
yarn add nuxt-security -
pnpm add nuxt-security
Imports
- Module registration (string)
import { nuxtSecurity } from 'nuxt-security'export default defineNuxtConfig({ modules: [ 'nuxt-security' ] }) - ModuleOptions
import { ModuleOptions } from 'nuxt-security'import type { ModuleOptions } from 'nuxt-security' - BasicAuth
import BasicAuth from 'nuxt-security/types/basic-auth'
import type { BasicAuth } from 'nuxt-security'
Quickstart
import { defineNuxtConfig } from 'nuxt';
import type { ModuleOptions } from 'nuxt-security';
const securityConfig: ModuleOptions = {
headers: {
contentSecurityPolicy: {
value: {
'default-src': ["'self'", "https://cdn.example.com"],
'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://cdn.example.com"],
'style-src': ["'self'", "'unsafe-inline'", "https://cdn.example.com"]
},
route: '/**'
},
xXSSProtection: { value: '1; mode=block', route: '/**' },
noSniff: { value: true, route: '/**' }
},
rateLimiter: {
value: {
tokens: 10,
interval: 30000,
headers: true,
driver: {
name: 'lru-cache',
options: { max: 1000, ttl: 60000 }
},
statusCode: 429,
statusMessage: 'Too Many Requests'
},
route: '/api/**'
},
allowedHTTPMethods: {
value: ['GET', 'POST', 'PUT', 'DELETE'],
route: '/api/**'
},
xssValidator: {
value: true,
route: '/forms/**'
},
basicAuth: {
value: {
name: process.env.BASIC_AUTH_USERNAME ?? 'admin',
pass: process.env.BASIC_AUTH_PASSWORD ?? 'password',
enabled: true,
message: 'Authentication Required'
},
route: '/admin/**'
}
};
export default defineNuxtConfig({
modules: [
'nuxt-security'
],
security: securityConfig
});