From 4313aa08ded540a70186057216e56ed1db050849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Raffray?= Date: Fri, 31 May 2024 16:36:36 +0200 Subject: [PATCH] disable owasp experimental permisisons policy --- .../2.headers/2.permissions-policy.md | 2 +- src/defaultConfig.ts | 22 +++++++++++++- test/headers.test.ts | 2 +- test/perRoute.test.ts | 30 +++++++++---------- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/docs/content/1.documentation/2.headers/2.permissions-policy.md b/docs/content/1.documentation/2.headers/2.permissions-policy.md index 1ae3aed2..43baa0d7 100644 --- a/docs/content/1.documentation/2.headers/2.permissions-policy.md +++ b/docs/content/1.documentation/2.headers/2.permissions-policy.md @@ -57,7 +57,7 @@ export default defineNuxtConfig({ By default, Nuxt Security will set following value for this header. ```http -Permissions-Policy: 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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=(); +Permissions-Policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=() ``` ## Available values diff --git a/src/defaultConfig.ts b/src/defaultConfig.ts index 7ea1a2e7..3cd534d4 100644 --- a/src/defaultConfig.ts +++ b/src/defaultConfig.ts @@ -39,32 +39,52 @@ export const defaultSecurityConfig = (serverlUrl: string): ModuleOptions => ({ xXSSProtection: '0', permissionsPolicy: { accelerometer: [], + /* Disable OWASP Experimental values 'ambient-light-sensor':[], + */ autoplay:[], + /* Disable OWASP Experimental values battery:[], + */ camera:[], 'display-capture':[], + /* Disable OWASP Experimental values 'document-domain':[], + */ 'encrypted-media':[], fullscreen:[], + /* Disable OWASP Experimental values gamepad:[], + */ geolocation:[], gyroscope:[], + /* Disable OWASP Experimental values 'layout-animations':['self'], + */ + /* Disable OWASP Experimental values 'legacy-image-formats':['self'], + */ magnetometer:[], microphone:[], midi:[], + /* Disable OWASP Experimental values 'oversized-images':['self'], + */ payment:[], 'picture-in-picture':[], 'publickey-credentials-get':[], + 'screen-wake-lock':[], + /* Disable OWASP Experimental values 'speaker-selection':[], + */ 'sync-xhr':['self'], + /* Disable OWASP Experimental values 'unoptimized-images':['self'], + */ + /* Disable OWASP Experimental values 'unsized-media':['self'], + */ usb:[], - 'screen-wake-lock':[], 'web-share':[], 'xr-spatial-tracking':[] } diff --git a/test/headers.test.ts b/test/headers.test.ts index 5c07280c..f3e84d34 100644 --- a/test/headers.test.ts +++ b/test/headers.test.ts @@ -92,7 +92,7 @@ describe('[nuxt-security] Headers', async () => { const ppHeaderValue = headers.get('permissions-policy') expect(ppHeaderValue).toBeTruthy() - expect(ppHeaderValue).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(ppHeaderValue).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') }) it('has `referrer-policy` header set with correct default value', async () => { diff --git a/test/perRoute.test.ts b/test/perRoute.test.ts index d60442fb..5c0feb2e 100644 --- a/test/perRoute.test.ts +++ b/test/perRoute.test.ts @@ -39,7 +39,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -77,7 +77,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -115,7 +115,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -237,7 +237,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -275,7 +275,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -313,7 +313,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -351,7 +351,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -389,7 +389,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -427,7 +427,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -465,7 +465,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(self), 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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(self), display-capture=(), encrypted-media=(), fullscreen=*, geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -505,7 +505,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(self), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(self), gamepad=(), geolocation=(*), gyroscope=(), layout-animations=(self), legacy-image-formats=(self), magnetometer=(), microphone=(), midi=(), oversized-images=(self), payment=(), picture-in-picture=(), publickey-credentials-get=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(self), display-capture=(), encrypted-media=(), fullscreen=(self), geolocation=(*), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -545,7 +545,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(self), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(self), gamepad=(), geolocation=(*), gyroscope=(), layout-animations=(self), legacy-image-formats=(self), magnetometer=(), microphone=(), midi=(), oversized-images=(self), payment=(), picture-in-picture=(), publickey-credentials-get=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(self), display-capture=(), encrypted-media=(), fullscreen=(self), geolocation=(*), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -586,7 +586,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -624,7 +624,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -663,7 +663,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { const pp = headers.get('permissions-policy') expect(csp).toBe("base-uri 'none'; default-src 'none'; connect-src 'self' https:; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src blob:; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' https: 'unsafe-inline' 'strict-dynamic'; upgrade-insecure-requests; worker-src 'self';") - expect(pp).toBe('accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=self, 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=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=()') + expect(pp).toBe('accelerometer=(), autoplay=(), camera=(), display-capture=self, encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()') }) it('sets all-resources security headers for an API route', async () => {