### Install Winston for Logging Source: https://nuxt-security.vercel.app/advanced/good-practices Installs the 'winston' module for application activity logging. ```bash npm i winston # or yarn ``` -------------------------------- ### Install Dependencies Source: https://nuxt-security.vercel.app/getting-started/contributing Install project dependencies using yarn. ```bash yarn ``` -------------------------------- ### Run Documentation in Development Source: https://nuxt-security.vercel.app/getting-started/contributing Start the documentation development server. ```bash yarn dev:docs ``` -------------------------------- ### Prepare for Development Source: https://nuxt-security.vercel.app/getting-started/contributing Run this command to generate type stubs before starting development. ```bash yarn dev:prepare ``` -------------------------------- ### Run Playground in Development Source: https://nuxt-security.vercel.app/getting-started/contributing Start the playground in development mode to test changes. ```bash yarn dev ``` -------------------------------- ### Install and Load Stripe.js Source: https://nuxt-security.vercel.app/advanced/strict-csp Install the Stripe.js npm package for payment processing. Load the Stripe instance within a component's onMounted hook. ```bash npm install @stripe/stripe-js ``` ```javascript ``` -------------------------------- ### Install ACL Module Source: https://nuxt-security.vercel.app/advanced/good-practices Installs the 'acl' module for implementing access control lists in your application. ```bash npm install acl # or yarn ``` -------------------------------- ### Install eslint-plugin-security-node Source: https://nuxt-security.vercel.app/advanced/good-practices Installs the 'eslint-plugin-security-node' development dependency to enforce Node.js security rules. ```bash npm install --save-dev eslint-plugin-security-node # or yarn ``` -------------------------------- ### Example External Image Source: https://nuxt-security.vercel.app/advanced/strict-csp Illustrates an image element loading from an external domain. ```html ``` -------------------------------- ### Install eslint-plugin-anti-trojan-source Source: https://nuxt-security.vercel.app/advanced/good-practices Installs the 'eslint-plugin-anti-trojan-source' development dependency to detect and prevent Trojan Source attacks. ```bash npm install --save-dev eslint-plugin-anti-trojan-source # or yarn ``` -------------------------------- ### Example External CDN Stylesheet Source: https://nuxt-security.vercel.app/advanced/strict-csp Demonstrates a stylesheet loaded from a Content Delivery Network (CDN). ```html ``` -------------------------------- ### Per-Route CSP Configuration Example Source: https://nuxt-security.vercel.app/headers/csp Demonstrates how to define Content Security Policy options on a per-route basis in Nuxt.js. Policies are resolved substitutively at each nested level. ```javascript 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 } } } } } }) ``` -------------------------------- ### Example Inline Script Source: https://nuxt-security.vercel.app/advanced/strict-csp Demonstrates an inlined script element directly within HTML. ```html ``` -------------------------------- ### Example Inline Style Source: https://nuxt-security.vercel.app/advanced/strict-csp Demonstrates an inlined style element directly within HTML. ```html ``` -------------------------------- ### Install BootstrapVueNext Nuxt Module Source: https://nuxt-security.vercel.app/advanced/strict-csp Install the BootstrapVueNext Nuxt module to integrate Bootstrap components. Configure it in your nuxt.config.ts file. ```bash npm install @bootstrap-vue-next/nuxt ``` ```javascript export default defineNuxtConfig({ modules: ['@bootstrap-vue-next/nuxt'], bootstrapVueNext: { composables: true, // Will include all composables }, css: ['bootstrap/dist/css/bootstrap.min.css'], }) ``` -------------------------------- ### Install Nuxt Security Module Source: https://nuxt-security.vercel.app/getting-started/installation Use this command to add the nuxt-security module to your Nuxt project. This automatically registers necessary route rules and middleware. ```bash npx nuxi@latest module add security ``` -------------------------------- ### Example External Nuxt Script Source: https://nuxt-security.vercel.app/advanced/strict-csp Shows a script element loaded from the application's origin, considered an 'external' resource by CSP. ```html ``` -------------------------------- ### Available X-Frame-Options Values Source: https://nuxt-security.vercel.app/headers/xframeoptions The xFrameOptions header can be configured with 'DENY' to prevent framing entirely, 'SAMEORIGIN' to allow framing only by same-origin ancestors, or false to disable the header. ```javascript xFrameOptions: 'DENY' | 'SAMEORIGIN' | false; ``` -------------------------------- ### Default X-Download-Options Value Source: https://nuxt-security.vercel.app/headers/xdownloadoptions By default, Nuxt Security sets the X-Download-Options header to 'noopen'. ```http X-Download-Options: noopen ``` -------------------------------- ### Create a Client-Side Nuxt Plugin for Scripts Source: https://nuxt-security.vercel.app/advanced/strict-csp Wrap external scripts in a client-side Nuxt plugin using the 'unhead' composable. This makes the script available globally via useNuxtApp. ```javascript import { useScript } from 'unhead'; export default defineNuxtPlugin((nuxtApp) => { const { $script } = useScript( { src: 'https://example.com/script.js', async: true, defer: true, } ) return { provide: { script: $script }, } }) ``` ```javascript const { $script } = useNuxtApp() ``` -------------------------------- ### Using useCsrfFetch and useCsrf Composables Source: https://nuxt-security.vercel.app/middleware/csrf Utilize the auto-imported `useCsrfFetch` composable to automatically add CSRF tokens to headers when making requests. Access the CSRF token value directly using the `useCsrf` composable. ```javascript // Wrapper around `useFetch` that automatically adds CSRF token in headers const { data, pending, error, refresh } = useCsrfFetch('/api/login', { query: 'value1' }) // Have access to the CSRF token value const { csrf } = useCsrf() ``` -------------------------------- ### Configure Cloudflare with Nuxt Security Source: https://nuxt-security.vercel.app/advanced/faq When using Cloudflare, disable Post-Build Optimizations and Javascript Detection. Load the Cloudflare script using useHead in client mode. ```javascript useHead({ script: [ { src: "/cdn-cgi/challenge-platform/scripts/jsd/main.js", crossorigin: true, referrerpolicy: "origin" } ] }, { mode: 'client' }) ``` ```typescript defineNuxtConfig({ security: { headers: { crossOriginEmbedderPolicy: 'unsafe-none', contentSecurityPolicy: { 'img-src': ["'self'", 'data:'], 'script-src': [ "'self'", 'https:', "'unsafe-inline'", "'strict-dynamic'", "'nonce-{{nonce}}'", "'unsafe-eval'" ] }, }, } }) ``` -------------------------------- ### Configure Strict-Transport-Security Header Source: https://nuxt-security.vercel.app/headers/stricttransportsecurity Set the Strict-Transport-Security header globally or per route. Replace with your desired configuration. ```javascript export default defineNuxtConfig({ // Global security: { headers: { strictTransportSecurity: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { strictTransportSecurity: , }, }, } } }) ``` -------------------------------- ### Lint Lockfile with npx Source: https://nuxt-security.vercel.app/advanced/good-practices Use npx to run the lockfile-lint command for validating your yarn.lock file. Ensure you specify the path to your lockfile and allowed hosts for package fetching. ```bash npx lockfile-lint --path yarn.lock --allowed-hosts npm yarn --validate-https ``` -------------------------------- ### Configure X-Permitted-Cross-Domain-Policies Header Source: https://nuxt-security.vercel.app/headers/xpermittedcrossdomainpolicies Set the X-Permitted-Cross-Domain-Policies header globally or per route using Nuxt configuration. Replace with desired policy values. ```javascript export default defineNuxtConfig({ // Global security: { headers: { xPermittedCrossDomainPolicies: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { xPermittedCrossDomainPolicies: , }, }, } } }) ``` -------------------------------- ### Configure ESLint for security-node Source: https://nuxt-security.vercel.app/advanced/good-practices Configures ESLint to use the 'security-node' plugin and its recommended rules for identifying potential security threats. ```json "plugins": [ "security-node" ], "extends": [ "plugin:security-node/recommended" ] ``` -------------------------------- ### Configure X-Frame-Options Globally or Per Route Source: https://nuxt-security.vercel.app/headers/xframeoptions Set the X-Frame-Options header behavior globally within the Nuxt config or on a per-route basis using routeRules. Replace with 'DENY', 'SAMEORIGIN', or false. ```javascript export default defineNuxtConfig({ // Global security: { headers: { xFrameOptions: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { xFrameOptions: , }, }, } } }) ``` -------------------------------- ### Apply Custom CSP Settings to Sub-Routes Source: https://nuxt-security.vercel.app/advanced/hooks Customize security options, like CSP `connect-src`, for specific sub-routes, such as `/admin/**`. This allows for granular control over security settings across different parts of your application. ```typescript export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('nuxt-security:routeRules', async(appSecurityOptions) => { const cspConnectSrc = await $fetch('https://secret-manager-api.com/api-route') // This example modifies the CSP only for `/admin/**` routes appSecurityOptions['/admin/**'] = defuReplaceArray( { headers: { contentSecurityPolicy: { "connect-src": [cspConnectSrc] } } }, appSecurityOptions['/admin/**'] ) }) }) ``` -------------------------------- ### Include External Script with useScript (Nuxt 3.11+) Source: https://nuxt-security.vercel.app/headers/csp Use `useScript` for the easiest and most universal way to include external scripts in Nuxt 3.11 and later. Refer to `useScript` documentation for available options. ```javascript useScript('https://example.com/script.js') ``` -------------------------------- ### Available X-Permitted-Cross-Domain-Policies Values Source: https://nuxt-security.vercel.app/headers/xpermittedcrossdomainpolicies Configure the xPermittedCrossDomainPolicies header with one of the available policy values: 'none', 'master-only', 'by-content-type', 'by-ftp-filename', 'all', or false to disable. ```javascript xPermittedCrossDomainPolicies: 'none' | 'master-only' | 'by-content-type' | 'by-ftp-filename' | 'all' | false; ``` -------------------------------- ### Page Meta for External Navigation Middleware Source: https://nuxt-security.vercel.app/advanced/faq Apply the `external-navigation` middleware to a specific page using `definePageMeta`. ```vue // example.vue ``` -------------------------------- ### Configure PayPal Checkout with Nuxt Security Source: https://nuxt-security.vercel.app/advanced/faq To integrate PayPal Checkout, configure specific route rules and security headers, including CSP for images and disabling strict transport security for the payment route. Load the PayPal SDK using useHead. ```typescript // nuxt.config.ts routeRules: { '/payment': { security: { headers: { crossOriginEmbedderPolicy: 'unsafe-none', crossOriginResourcePolicy: 'cross-origin', }, } }, }, security: { headers: { contentSecurityPolicy: { 'img-src': [ "'self'", 'data:', 'https://paypal.com', 'https://www.paypalobjects.com', ], }, strictTransportSecurity: { magAge: 0 }, }, }, ``` ```javascript useHead({ // Paypal SDK to show Paypal button on Payment Page script: [ { src: `https://www.paypal.com/sdk/js?client-id=YOURCLIENTID&components=buttons,marks¤cy=USD&disable-funding=card`, crossorigin: 'anonymous', }, ], noscript: [{ children: 'JavaScript is required' }], }); ``` -------------------------------- ### Available Values for X-Content-Type-Options Source: https://nuxt-security.vercel.app/headers/xcontenttypeoptions The xContentTypeOptions header can be configured with 'nosniff' or false. ```typescript xContentTypeOptions: 'nosniff' | false ``` -------------------------------- ### Nuxt Security Default Configuration Source: https://nuxt-security.vercel.app/getting-started/configuration Shows the default configuration values for the Nuxt Security module. These settings are applied automatically unless overridden. ```javascript security: { strict: false, headers: { crossOriginResourcePolicy: 'same-origin', crossOriginOpenerPolicy: 'same-origin', crossOriginEmbedderPolicy: 'credentialless', contentSecurityPolicy: { 'base-uri': ["'none'"], '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'"], 'script-src': ["'self'", 'https:', "'unsafe-inline'", "'strict-dynamic'", "'nonce-{{nonce}}'"], 'upgrade-insecure-requests': true }, originAgentCluster: '?1', referrerPolicy: 'no-referrer', strictTransportSecurity: { maxAge: 15552000, includeSubdomains: true, }, xContentTypeOptions: 'nosniff', xDNSPrefetchControl: 'off', xDownloadOptions: 'noopen', xFrameOptions: 'SAMEORIGIN', xPermittedCrossDomainPolicies: 'none', xXSSProtection: '0', permissionsPolicy: { camera: [], 'display-capture': [], fullscreen: [], geolocation: [], microphone: [] } }, requestSizeLimiter: { maxRequestSizeInBytes: 2000000, maxUploadFileRequestInBytes: 8000000, throwError: true }, rateLimiter: { tokensPerInterval: 150, interval: 300000, headers: false, driver: { name: 'lruCache' }, throwError: true }, xssValidator: { throwError: true }, corsHandler: { origin: serverlUrl, methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'], preflight: { statusCode: 204 }, }, allowedMethodsRestricter: { methods: '*', throwError: true }, hidePoweredBy: true, basicAuth: false, enabled: true, csrf: false, nonce: true, removeLoggers: true, ssg: { meta: true, hashScripts: true, hashStyles: false, nitroHeaders: true, exportToPresets: true, }, sri: true } ``` -------------------------------- ### Fetch Specific Fields with useFetch Source: https://nuxt-security.vercel.app/advanced/good-practices Use the `pick` option with `useFetch` to retrieve only the necessary fields from an API response, preventing the leakage of sensitive data. ```javascript const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains',{ pick: ['title'] }) ``` -------------------------------- ### Configure Cross-Origin-Resource-Policy Globally or Per Route Source: https://nuxt-security.vercel.app/headers/crossoriginresourcepolicy Configure the Cross-Origin-Resource-Policy header globally within the Nuxt config or on a per-route basis using routeRules. Replace with 'same-site', 'same-origin', 'cross-origin', or false. ```javascript export default defineNuxtConfig({ // Global security: { headers: { crossOriginResourcePolicy: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { crossOriginResourcePolicy: , }, }, } } }) ``` -------------------------------- ### Nuxt Config for SSG CSP Source: https://nuxt-security.vercel.app/headers/csp Configure Nuxt Security for SSG CSP by enabling meta tags, script hashing, and defining global CSP headers. Note that nonce placeholders are ignored in SSG mode. ```javascript 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'" }, }, }, } } }) ``` -------------------------------- ### defu: Standard Array Merging Source: https://nuxt-security.vercel.app/advanced/auto-imports Compares defuReplaceArray with the standard defu utility, which merges arrays by appending new elements. This is shown for contrast. ```javascript const existingArray = ['a', 'b'] const newArray = ['c'] const result = defu(newArray, existingArray) // ['a', 'b', 'c'] ``` -------------------------------- ### Configure Google Auth with Nuxt Security Source: https://nuxt-security.vercel.app/advanced/faq When using Google Auth's Sign In modal method, set `crossOriginOpenerPolicy` to `same-origin-allow-popups`. ```typescript // nuxt.config.ts security:{ headers: { crossOriginOpenerPolicy: 'same-origin-allow-popups' } } ``` -------------------------------- ### Configure Referrer-Policy Header Source: https://nuxt-security.vercel.app/headers/referrerpolicy Set the Referrer-Policy header globally or per route. You can also disable the header by setting `referrerPolicy` to `false`. ```javascript export default defineNuxtConfig({ // Global security: { headers: { referrerPolicy: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { referrerPolicy: , }, }, } } }) ``` -------------------------------- ### Default Strict CSP Configuration Source: https://nuxt-security.vercel.app/headers/csp This configuration enables Strict CSP with default settings for both SSR and SSG. It includes specific directives for script-src, style-src, and other security headers. ```javascript 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 } }) ``` -------------------------------- ### Configure CSP Header Globally or Per Route Source: https://nuxt-security.vercel.app/headers/csp Configure the Content Security Policy header globally within your Nuxt config or on a per-route basis using route rules. Replace with your desired CSP configuration. ```javascript export default defineNuxtConfig({ // Global security: { headers: { contentSecurityPolicy: , }, }, // Per route routeRules: { '/custom-route': { security: { headers: { contentSecurityPolicy: , }, }, } } }) ``` -------------------------------- ### Middleware for External Navigation Source: https://nuxt-security.vercel.app/advanced/faq Create a Nuxt middleware to redirect specific routes to external URLs, useful for handling external links. ```javascript // middleware/external-navigation.ts export default defineNuxtRouteMiddleware((to) => { const routesForExternalLinks = ['/example'] // Add any other routes you want to act as external links if ( import.meta.client && !useNuxtApp().isHydrating && to.path && routesForExternalLinks.includes(to.path) ) { window.location.href = to.fullPath } }) ``` -------------------------------- ### Configure Nuxt Security Module Source: https://nuxt-security.vercel.app/getting-started/installation Add the security section to your nuxt.config.js file to customize module options. Refer to the documentation for available security configurations. ```javascript security: { // Options } ``` -------------------------------- ### Merging Security Rules with Addition using defu Source: https://nuxt-security.vercel.app/getting-started/usage Add new values to existing security settings, such as CSP directives, for a route by using the standard defu utility in a Nitro plugin. Ensure defu is imported. ```typescript // You will need to import defu import { defu } from 'defu' export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => { routeRules['/some/route'] = defu( { headers: { contentSecurityPolicy: { "script-src": ["'self'", "..."] // The values "'self' ..." will be added to the existing values } } }, routeRules['/some/route'] // The other existing rules for /some/route will be preserved ) }) }) ``` -------------------------------- ### Allow Inline Scripts with Hashes (CSP Level 2) Source: https://nuxt-security.vercel.app/advanced/strict-csp Hashes allow specific inline scripts by providing a SHA hash of the script's content in the CSP header. The browser computes the hash of the inline script and compares it to the provided hash. ```html ``` ```http Content-Security-Policy: script-src 'sha256-......' ``` -------------------------------- ### Available Values for Origin-Agent-Cluster Source: https://nuxt-security.vercel.app/headers/originagentcluster The originAgentCluster header can be configured with either '?1' to enable origin-keyed clusters or false to disable it. ```typescript originAgentCluster: '?1' | false, ``` -------------------------------- ### Enable Basic Auth Globally Source: https://nuxt-security.vercel.app/middleware/basic-auth Enable the Basic Auth middleware globally in your Nuxt application by configuring it within the `nuxt.config.ts` file. This ensures all incoming traffic is subject to authentication. ```typescript export default defineNuxtConfig({ security: { basicAuth: { // options } } }) ``` -------------------------------- ### Configure Strict Permissions Policy Source: https://nuxt-security.vercel.app/advanced/improve-security Define the Permissions Policy in strict mode by specifying allowed features. Review your application's needs and uncomment/configure directives as necessary. Some features are experimental and may not be widely implemented. ```typescript export default defineNuxtConfig({ security: { headers: { permissionsPolicy: { accelerometer: [], //'ambient-light-sensor':[], autoplay:[], //battery:[], camera:[], 'display-capture':[], //'document-domain':[], 'encrypted-media':[], fullscreen:[], //gamepad:[], geolocation:[], gyroscope:[], //'layout-animations':['self'], //'legacy-image-formats':['self'], magnetometer:[], microphone:[], midi:[], //'oversized-images':['self'], payment:[], 'picture-in-picture':[], 'publickey-credentials-get':[], 'screen-wake-lock':[], //'speaker-selection':[], 'sync-xhr':['self'], //'unoptimized-images':['self'], //'unsized-media':['self'], usb:[], 'web-share':[], 'xr-spatial-tracking':[] } } } }) ```