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': {
security: {
headers: {
contentSecurityPolicy: <OPTIONS>,
},
},
}
}
})
You can also disable this header by contentSecurityPolicy: false
.
Default value
By default, Nuxt Security will set the following value for this header:
Content-Security-Policy: base-uri 'none'; font-src 'self' https: data:; form-action 'self'; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' https: 'unsafe-inline' 'strict-dynamic' 'nonce-{{nonce}}'; upgrade-insecure-requests;
Available values
The contentSecurityPolicy
header can be configured with following values.
contentSecurityPolicy: {
'child-src'?: CSPSourceValue[] false;
'connect-src'?: CSPSourceValue[] | false;
'default-src'?: CSPSourceValue[] | false;
'font-src'?: CSPSourceValue[] | false;
'frame-src'?: CSPSourceValue[] | false;
'img-src'?: CSPSourceValue[] | false;
'manifest-src'?: CSPSourceValue[] | false;
'media-src'?: CSPSourceValue[] | false;
'object-src'?: CSPSourceValue[] | false;
'prefetch-src'?: CSPSourceValue[] | false;
'script-src'?: CSPSourceValue[] | false;
'script-src-elem'?: CSPSourceValue[] | false;
'script-src-attr'?: CSPSourceValue[] | false;
'style-src'?: CSPSourceValue[] | false;
'style-src-elem'?: CSPSourceValue[] | false;
'style-src-attr'?: CSPSourceValue[] | false;
'worker-src'?: CSPSourceValue[] | false;
'base-uri'?: CSPSourceValue[] | false;
'sandbox'?: CSPSandboxValue[] | false;
'form-action'?: CSPSourceValue[] | false;
'frame-ancestors'?: ("'self'" | "'none'" | string)[] | false;
'report-uri'?: string[] | false;
'report-to'?: string | false;
'upgrade-insecure-requests'?: boolean;
} | false
CSPSourceValue type
CSPSandboxValue type
Strict CSP
Nuxt Security helps you increase the security of your site by enabling Strict CSP support for both SSR and SSG applications.
For further reading about Strict CSP and how to handle specific cases, please consult our Adanced Section about Strict CSP
- For SSR applications, Nuxt Security implements strict CSP via nonces. A one-time cryptographically-generated random nonce is generated at runtime by the server for each request of a page.
- For SSG applications, Nuxt Security implements strict CSP via hashes. At static build-time, Nuxt Security computes the SHA hashes of the elements that are allowed to execute on your site.
By default, Strict CSP will be enabled on your site. The following default configuration options are used:
export default defineNuxtConfig({
security: {
nonce: true, // Enables HTML nonce support in SSR mode
ssg: {
meta: true, // Enables CSP as a meta tag in SSG mode
hashScripts: true, // Enables CSP hash support for scripts in SSG mode
hashStyles: false // Disables CSP hash support for styles in SSG mode (recommended)
},
headers: {
contentSecurityPolicy: {
'script-src': [
"'self'", // Fallback value, will be ignored by most modern browsers (level 3)
"https:", // Fallback value, will be ignored by most modern browsers (level 3)
"'unsafe-inline'", // Fallback value, will be ignored by almost any browser (level 2)
"'strict-dynamic'", // Strict CSP via 'strict-dynamic', supported by most modern browsers (level 3)
"'nonce-{{nonce}}'" // Enables CSP nonce support for scripts in SSR mode, supported by almost any browser (level 2)
],
'style-src': [
"'self'", // Enables loading of stylesheets hosted on same origin
"https:", // For increased security, replace by the specific hosting domain or file name of your external stylesheets
"'unsafe-inline'" // Recommended default for most Nuxt apps
],
'base-uri': ["'none'"],
'img-src': ["'self'", "data:"], // Add relevant https://... sources if you load images from external sources
'font-src': ["'self'", "https:", "data:"], // For increased security, replace by the specific sources for fonts
'object-src': ["'none'"],
'script-src-attr': ["'none'"],
'upgrade-insecure-requests': true
}
},
sri: true
}
})
Server Side Rendering (SSR)
Nuxt Security provides first-class support of SSR apps via 'strict-dynamic' and nonces.
In SSR mode, Strict CSP is enabled when you set the nonce
option and the "'nonce-{{nonce}}'"
placeholders:
export default defineNuxtConfig({
// Global
security: {
nonce: true, // Enables HTML nonce support in SSR mode
headers: {
contentSecurityPolicy: {
'script-src': [
"'strict-dynamic'", // Modify with your custom CSP sources
"'nonce-{{nonce}}'" // Enables CSP nonce support for scripts in SSR mode, supported by almost any browser (level 2)
]
}
},
},
// Per route
routeRules: {
'/custom-route': {
security: {
nonce: false,
headers: {
contentSecurityPolicy: {
'script-src': "self 'unsafe-inline'"
},
},
},
}
}
})
nonce
: Set this option totrue
to parse all<script>
,<link>
and<style>
tags in your application and add the nonce value to these. The module parses all inline elements as well as all external resources."'nonce-{{nonce}}'"
placeholder: Include this value in any individual policy that you want to be governed by nonce.
Note: Nonce only works for SSR. The nonce
option and the "'nonce-{{nonce}}'"
placeholders are ignored when you build your app for SSG via nuxi generate
.
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="base-uri 'none'; font-src 'self' https: data:; form-action 'self'; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' https: 'unsafe-inline' 'strict-dynamic' 'sha256-{{hash}}'; upgrade-insecure-requests;">
For SSG apps, Strict CSP is enabled when you set the ssg
and sri
options:
export default defineNuxtConfig({
// Global
security: {
ssg: {
meta: true, // Enables CSP as a meta tag in SSG mode
hashScripts: true, // Enables CSP hash support for scripts in SSG mode
hashStyles: false // Disables CSP hash support for styles in SSG mode (recommended)
exportToPresets: true // Export security headers to Nitro presets
},
sri: true,
headers: {
contentSecurityPolicy: {
'script-src': [
"'strict-dynamic'", // Modify with your custom CSP sources
// The nonce-{{nonce}} placeholder is not required and will be ignored in SSG mode
]
}
}
},
// Per route
routeRules: {
'/custom-route': {
security: {
ssg: false,
sri: false,
headers: {
contentSecurityPolicy: {
'script-src': "self 'unsafe-inline'"
},
},
},
}
}
})
Nuxt Security will generate script hashes and style hashes for you according to the ssg
option:
hashScripts
: Set this option totrue
to parse all inline scripts as well as all external scripts. Nuxt-Security will compute the hashes of inline scripts and find theintegrity
attributes of external scripts, and will add them to yourscript-src
policy.hashStyles
: Set this option totrue
to parse all inline styles as well as all external styles. Nuxt-Security will compute the hashes of inline styles and find theintegrity
attributes of external styles, and will add them to yourstyle-src
policy.
ssg: hashStyles
option to true
.
⚠ This is because Nuxt's mechanism for Client-Side hydration of styles could be blocked by CSP in that case.
For further discussion and alternatives, please refer to our Advanced Section on CSP.
integrity
attributes of all your bundled assets if you set the sri
option to true
. For unbundled assets, you may need to set the integrity
attribute manually.
Please see below our section on Integrity Hashes For SSG
Note: Hashes only work for SSG. The ssg
options are ignored when you build your app for SSR via nuxi build
.
Per-route configuration
All Content Security Policy options can be defined on a per-route level.
As examplified below, Nuxt Security resolves the contentSecurityPolicy
options substitutively at each nested level.
export default defineNuxtConfig({
// Global
security: {
headers: {
contentSecurityPolicy: {
'img-src': false // By default, no images can be loaded
}
}
}
// Per route
routeRules: {
'/some-prefix/**': {
security: {
headers: {
contentSecurityPolicy: {
'img-src': ["'self'"] // Self-hosted images can be loaded for routes beginning with /some-prefix/
}
}
}
},
'/some-prefix/some-route/**': {
security: {
headers: {
contentSecurityPolicy: {
'img-src': ["'self'", "https:"] // Self-hosted AND https: images can be loaded for routes beginning with /some-prefix/some-route/
}
}
}
},
'/some-prefix/some-route/some-page': {
security: {
headers: {
contentSecurityPolicy: {
'img-src': ["'self'"] // ONLY self-hosted images can be loaded on /some-prefix/some-route/some-page
}
}
}
}
}
})
Including External Scripts
You can include any external script (Google Analytics, Stripe, Cloudflare Turnstile, etc.) in your application without compromising the Strict CSP protection offered by Nuxt Security.
'strict-dynamic'
, nonce
and ssg
options.
If you change these default values, please refer to our Advanced Section on CSP for alternatives.
- Since Nuxt 3.11, the easiest and universal way to include external scripts is via
useScript
useScript('https://example.com/script.js')
Please see useScript for available options and usage.
- Before Nuxt 3.11, you can also include your external scripts via
useHead
useHead({
script: [
{
src: 'https://example.com/script.js',
},
{
mode: 'client' // 'client' option is required in SSG mode
}
]
})
- In all cases, you can also include external scripts directly in the HTML source
<script src="https://example.com/script.js" integrity="sha384-....." crossorigin="anonymous" />
When inserting scripts directly in HTML, you will need to provide an integrity hash if you are using SSG mode. Many standard scripts (e.g. Google Analytics) do not provide an integrity hash, therefore this method is not compatible with SSG.