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.

ℹ Read more about this header here.

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'">
ℹ Read more about this here.

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:

  1. useHead composable - If you are dynamically adding script or link tags in your application using the useHead 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' })
  1. 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 the useNonce composable:
const nonce = useNonce()

You can then use it with Nuxt Image like following:

<NuxtImg src="https://localhost:8000/api/image/xyz" :nonce="nonce" />