Content Security Policy
Enabled Prevent unwanted content from being injected in your app.
Content Security Policy (CSP) helps prevent unwanted content from being injected/loaded into your webpages. This can mitigate cross-site scripting (XSS) vulnerabilities, clickjacking, formjacking, malicious frames, unwanted trackers, and other web client-side attacks.
Usage
This header is enabled by default but you can change its behavior like following.
export default defineNuxtConfig({ // Global security: { headers: { contentSecurityPolicy: <OPTIONS>, }, }, // Per route routeRules: { '/custom-route': { headers: { 'Content-Security-Policy': <OPTIONS> }, } }})
You can also disable this header by contentSecurityPolicy: false
.
Default value
By default, Nuxt Security will set following value for this header.
Content-Security-Policy: base-uri 'self'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; upgrade-insecure-requests
Available values
The contentSecurityPolicy
header can be configured with following values.
contentSecurityPolicy: { 'child-src'?: CSPSourceValue[]; 'connect-src'?: CSPSourceValue[]; 'default-src'?: CSPSourceValue[]; 'font-src'?: CSPSourceValue[]; 'frame-src'?: CSPSourceValue[]; 'img-src'?: CSPSourceValue[]; 'manifest-src'?: CSPSourceValue[]; 'media-src'?: CSPSourceValue[]; 'object-src'?: CSPSourceValue[]; 'prefetch-src'?: CSPSourceValue[]; 'script-src'?: CSPSourceValue[]; 'script-src-elem'?: CSPSourceValue[]; 'script-src-attr'?: CSPSourceValue[]; 'style-src'?: CSPSourceValue[]; 'style-src-elem'?: CSPSourceValue[]; 'style-src-attr'?: CSPSourceValue[]; 'worker-src'?: CSPSourceValue[]; 'base-uri'?: CSPSourceValue[]; 'sandbox'?: CSPSandboxValue[]; 'form-action'?: CSPSourceValue[]; 'frame-ancestors'?: ("'self'" | "'none'" | string)[]; 'navigate-to'?: ("'self'" | "'none'" | "'unsafe-allow-redirects'" | string)[]; 'report-uri'?: string[]; 'report-to'?: string[]; 'upgrade-insecure-requests'?: boolean;} | false
CSPSourceValue type
CSPSandboxValue type
Static site generation (SSG)
This module is meant to work with SSR apps, but you can also use this module in SSG apps where you will get a Content Security Policy (CSP) support via <meta http-equiv>
tag.
This will result in following code being added to your static app <head>
tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
By default, Nuxt Security will generate script hashes for you. If you do not want this functionality you can disable it like following:
export default defineNuxtConfig({ security: { ssg: { hashScripts: false } }})
Nonce
To further increase CSP security, you can use a nonce-based strict csp. This can be configured as follows:
export default defineNuxtConfig({ security: { nonce: true, headers: { contentSecurityPolicy: { 'style-src': process.env.NODE_ENV === 'production' ? [ "'self'", // backwards compatibility for older browsers that don't support strict-dynamic "'nonce-{{nonce}}'", "'strict-dynamic'", ] : // In dev mode, we allow unsafe-inline so that hot reloading keeps working ["'self'", "'unsafe-inline'"], 'script-src': [ "'self'", // fallback value for older browsers, automatically removed if `strict-dynamic` is supported. "'nonce-{{nonce}}'", "'strict-dynamic'" ], 'script-src-attr': [ "'self'", // fallback value for older browsers, automatically removed if `strict-dynamic` is supported. "'nonce-{{nonce}}'", "'strict-dynamic'" ] } } }})
This will add a nonce
attribute to all <script>
, <link>
and <style>
tags in your application.
Note that to allow hot reloading during development, we conditionally add 'unsafe-inline'
to the style-src
value.
The nonce
value is generated per request and is added to the CSP header. This behaviour can be tweaked on a route level by using the routeRules
option:
export default defineNuxtConfig({ routeRules: { '/api/custom-route': { nonce: false // do not check nonce for this route (1) }, '/api/other-route': { nonce: { mode: 'check' } // do not generate a new nonce for this route, but check it against the existing one (2) } }})
There are two ways to use nonce
in your application. Check out both of them and decide which one suits your needs best:
useHead
composable - If you are dynamically adding script or link tags in your application using theuseHead
composable, all nonce values will be automatically added. However, take note that due to a current bug in unjs/unhead, you'll need to add a workaround when using ssr to prevent double loading and executing of your scripts when using nonce.
// workaround unjs/unhead bug for double injection when using nonce// by setting the mode to 'server'// see: https://github.com/unjs/unhead/issues/136 useHead({ script: [{ src: 'https://example.com/script.js' }] }, { mode: 'server' })
- Directly inserting tags into DOM - If you are unable or unwilling to use
useHead
and are inserting directly into the DOM (e.g.document.createElement
), you can get the current valid nonce value using theuseNonce
composable:
const nonce = useNonce()
You can then use it with Nuxt Image like following:
<NuxtImg src="https://localhost:8000/api/image/xyz" :nonce="nonce" />