diff --git a/src/defaultConfig.ts b/src/defaultConfig.ts index b8faf492..0e9aa164 100644 --- a/src/defaultConfig.ts +++ b/src/defaultConfig.ts @@ -8,8 +8,8 @@ export const defaultSecurityConfig = (serverlUrl: string): Partial { expect(cspHeaderValue).toBeTruthy() expect(nonceValue).toBeDefined() expect(nonceValue).toHaveLength(24) - expect(cspHeaderValue).toBe(`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-${nonceValue}'; upgrade-insecure-requests;`) + expect(cspHeaderValue).toBe(`base-uri 'none'; default-src '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-${nonceValue}'; upgrade-insecure-requests;`) }) it('has `cross-origin-embedder-policy` header set with correct default value', async () => { @@ -92,7 +92,7 @@ describe('[nuxt-security] Headers', async () => { const ppHeaderValue = headers.get('permissions-policy') expect(ppHeaderValue).toBeTruthy() - expect(ppHeaderValue).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') }) it('has `referrer-policy` header set with correct default value', async () => { @@ -114,7 +114,7 @@ describe('[nuxt-security] Headers', async () => { const stsHeaderValue = headers.get('strict-transport-security') expect(stsHeaderValue).toBeTruthy() - expect(stsHeaderValue).toBe('max-age=15552000; includeSubDomains;') + expect(stsHeaderValue).toBe('max-age=31536000; includeSubDomains;') }) it('has `x-content-type-options` header set with correct default value', async () => { @@ -158,7 +158,7 @@ describe('[nuxt-security] Headers', async () => { const xfoHeaderValue = headers.get('x-frame-options') expect(xfoHeaderValue).toBeTruthy() - expect(xfoHeaderValue).toBe('SAMEORIGIN') + expect(xfoHeaderValue).toBe('DENY') }) it('has `x-permitted-cross-domain-policies` header set with correct default value', async () => { diff --git a/test/perRoute.test.ts b/test/perRoute.test.ts index ef2c010d..f2a425f0 100644 --- a/test/perRoute.test.ts +++ b/test/perRoute.test.ts @@ -29,17 +29,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -67,17 +67,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -105,17 +105,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -152,10 +152,10 @@ describe('[nuxt-security] Per-route Configuration', async () => { const xxp = headers.get('x-xss-protection') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') @@ -194,10 +194,10 @@ describe('[nuxt-security] Per-route Configuration', async () => { const xxp = headers.get('x-xss-protection') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') @@ -227,17 +227,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin-allow-popups') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -265,17 +265,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin-allow-popups') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -303,17 +303,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBeNull() expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBeNull() - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -341,17 +341,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBeNull() expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBeNull() - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -379,17 +379,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBeNull() expect(coop).toBe('same-origin') expect(coep).toBe('credentialless') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -417,17 +417,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-site') expect(coop).toBeNull() expect(coep).toBe('credentialless') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -455,17 +455,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('cross-origin') expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("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:; upgrade-insecure-requests; media-src 'none';") + expect(csp).toBe("base-uri 'none'; default-src '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:; upgrade-insecure-requests; media-src 'none';") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') expect(sts).toBe('max-age=1; includeSubDomains; preload;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(self), display-capture=(), fullscreen=*, geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -495,17 +495,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-site') expect(coop).toBeNull() expect(coep).toBe('credentialless') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') expect(sts).toBe('max-age=2;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(self), display-capture=(), fullscreen=(self), geolocation=(*), microphone=()') + 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=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -535,7 +535,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-site') expect(coop).toBe('same-origin-allow-popups') expect(coep).toBe('credentialless') - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer-when-downgrade') expect(sts).toBe('max-age=1; preload;') @@ -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('camera=(self), display-capture=(), fullscreen=(self), geolocation=(*), microphone=()') + 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=()') const foo = headers.get('foo') const foo2 = headers.get('foo2') @@ -576,17 +576,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBeNull() expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src https:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self'; upgrade-insecure-requests;") + expect(csp).toBe("default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src https:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self'; upgrade-insecure-requests;") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') expect(sts).toBe('max-age=10; preload;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -614,17 +614,17 @@ describe('[nuxt-security] Per-route Configuration', async () => { expect(corp).toBe('same-origin') expect(coop).toBe('same-origin') expect(coep).toBe('require-corp') - expect(csp).toBe("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'; upgrade-insecure-requests; manifest-src 'none';") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests; manifest-src 'none';") expect(oac).toBe('?1') expect(rp).toBe('no-referrer') expect(sts).toBe('max-age=10; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdpc).toBe('off') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') - expect(pp).toBe('camera=(), display-capture=(), fullscreen=(), geolocation=(), microphone=()') + 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=()') const foo = headers.get('foo') expect(foo).toBe('bar') @@ -662,8 +662,8 @@ describe('[nuxt-security] Per-route Configuration', async () => { const csp = headers.get('content-security-policy') const pp = headers.get('permissions-policy') - expect(csp).toBe("base-uri 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src blob:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' https: 'unsafe-inline' 'strict-dynamic'; upgrade-insecure-requests;") - expect(pp).toBe('camera=(), display-capture=self, fullscreen=(), geolocation=(), microphone=()') + expect(csp).toBe("base-uri 'none'; default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src blob:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' https: 'unsafe-inline' 'strict-dynamic'; upgrade-insecure-requests;") + 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=()') }) it('sets all-resources security headers for an API route', async () => { @@ -697,10 +697,10 @@ describe('[nuxt-security] Per-route Configuration', async () => { const xxp = headers.get('x-xss-protection') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') @@ -746,10 +746,10 @@ describe('[nuxt-security] Per-route Configuration', async () => { const xxp = headers.get('x-xss-protection') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') }) @@ -785,10 +785,10 @@ describe('[nuxt-security] Per-route Configuration', async () => { const xxp = headers.get('x-xss-protection') expect(rp).toBe('no-referrer') - expect(sts).toBe('max-age=15552000; includeSubDomains;') + expect(sts).toBe('max-age=31536000; includeSubDomains;') expect(xcto).toBe('nosniff') expect(xdo).toBe('noopen') - expect(xfo).toBe('SAMEORIGIN') + expect(xfo).toBe('DENY') expect(xpcdp).toBe('none') expect(xxp).toBe('0') }) @@ -958,7 +958,7 @@ describe('[nuxt-security] Per-route Configuration', async () => { const { headers } = res const csp = headers.get('content-security-policy') expect(csp).toBeDefined() - expect(csp).toBe("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'; upgrade-insecure-requests;") + expect(csp).toBe("base-uri 'none'; default-src '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'; upgrade-insecure-requests;") const rp = headers.get('referrer-policy') expect(rp).toBeDefined() expect(rp).toBe('no-referrer') diff --git a/test/runtimeHooks.test.ts b/test/runtimeHooks.test.ts index da0bec1e..e4e68d5b 100644 --- a/test/runtimeHooks.test.ts +++ b/test/runtimeHooks.test.ts @@ -9,27 +9,27 @@ await setup({ describe('[nuxt-security] runtime hooks', () => { it('expect csp to be set to static values by the (deprecated) headers runtime hook', async () => { const res = await fetch('/headers-static') - expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' static-value.com; upgrade-insecure-requests;\"") + expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' static-value.com; upgrade-insecure-requests;\"") expect(res.headers.get('X-Powered-By')).toBeNull() }) it('expect csp to be set to dynamically-fetched values by the (deprecated) headers runtime hook', async () => { const res = await fetch('/headers-dynamic') - expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' *.dynamic-value.com; upgrade-insecure-requests;\"") + expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' *.dynamic-value.com; upgrade-insecure-requests;\"") expect(res.headers.get('X-Powered-By')).toBeNull() }) it('expect any security option to be modified by the new routeRules runtime hook', async () => { const res = await fetch('/rules-static') - expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' static-value.com; upgrade-insecure-requests;\"") + expect(res.headers.get('Content-Security-Policy')).toMatchInlineSnapshot("\"base-uri 'none'; default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' static-value.com; upgrade-insecure-requests;\"") expect(res.headers.get('X-Powered-By')).toEqual('Nuxt') }) it('expect any security option to be dynamically-fetched by the new routeRules runtime hook', async () => { const res = await fetch('/rules-dynamic') const csp = res.headers.get('Content-Security-Policy') - expect(csp).toMatchInlineSnapshot("\"base-uri 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' *.dynamic-value.com; upgrade-insecure-requests;\"") + expect(csp).toMatchInlineSnapshot("\"base-uri 'none'; default-src 'none'; font-src 'self' https: data:; form-action 'self'; frame-ancestors * weird-value.com; img-src 'self' data:; object-src 'none'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; script-src 'self' *.dynamic-value.com; upgrade-insecure-requests;\"") expect(res.headers.get('X-Powered-By')).toEqual('Nuxt') }) }) \ No newline at end of file diff --git a/test/ssrNonce.test.ts b/test/ssrNonce.test.ts index b98b3e9e..6ca516d8 100644 --- a/test/ssrNonce.test.ts +++ b/test/ssrNonce.test.ts @@ -63,7 +63,7 @@ describe('[nuxt-security] Nonce', async () => { const noncesInCsp = cspHeaderValue?.match(/'nonce-(.*?)'/)?.length ?? 0 expect(noncesInCsp).toBe(0) - expect(cspHeaderValue).toBe("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'; script-src 'self' 'strict-dynamic'; upgrade-insecure-requests;") + expect(cspHeaderValue).toBe("base-uri 'none'; default-src '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'; script-src 'self' 'strict-dynamic'; upgrade-insecure-requests;") }) it('injects `nonce` attribute in style tags', async () => {