diff --git a/docs/content/2.usage/1.nuxt-img.md b/docs/content/2.usage/1.nuxt-img.md index bb2d34b05..a68aa83d1 100644 --- a/docs/content/2.usage/1.nuxt-img.md +++ b/docs/content/2.usage/1.nuxt-img.md @@ -380,7 +380,7 @@ Set `loading="lazy"` to defer loading of an image until it appears in the viewpo ``` -### `nonce` +### `nonce` [DEPRECATED] This is a [native](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) global attribute that defines a cryptographic nonce (number used once) that can be used by Content Security Policy to determine whether or not a given fetch will be allowed to proceed for a given element. Providing a nonce allows you to avoid using the CSP `unsafe-inline` directive, which would allowlist *all* inline script or styles. @@ -399,6 +399,13 @@ Providing a nonce allows you to avoid using the CSP `unsafe-inline` directive, w const nonce = useNonce() ``` +::warning +This property was available in Nuxt Image v1, but is deprecated in Nuxt Image v2. + +Having `nonce` be configurable introduces significant security risks as there is no guarantee the provided nonce is cryptographfically secure, generated according to the specification, and unique across the app. + +It's best to let battle-tested security modules like [Nuxt Security](https://nuxt.com/modules/security) handle the nonce generation. +:: ## Events diff --git a/src/runtime/components/NuxtImg.vue b/src/runtime/components/NuxtImg.vue index 5172ca13e..069e09cdc 100644 --- a/src/runtime/components/NuxtImg.vue +++ b/src/runtime/components/NuxtImg.vue @@ -111,7 +111,6 @@ if (import.meta.server && props.preload) { link: [{ rel: 'preload', as: 'image', - nonce: props.nonce, crossorigin: normalizedAttrs.value.crossorigin, href: isResponsive ? sizes.value.src : src.value, ...(sizes.value.sizes && { imagesizes: sizes.value.sizes }), diff --git a/src/runtime/components/NuxtPicture.vue b/src/runtime/components/NuxtPicture.vue index e786af260..72a1f3061 100644 --- a/src/runtime/components/NuxtPicture.vue +++ b/src/runtime/components/NuxtPicture.vue @@ -52,7 +52,7 @@ const emit = defineEmits<{ }>() const _attrs = useAttrs() -const imageAttrNames = new Set(['alt', 'referrerpolicy', 'usemap', 'longdesc', 'ismap', 'loading', 'crossorigin', 'decoding', 'nonce']) +const imageAttrNames = new Set(['alt', 'referrerpolicy', 'usemap', 'longdesc', 'ismap', 'loading', 'crossorigin', 'decoding']) const attrs = computed(() => { const attrs: Record<'img' | 'picture', Record> = { img: { @@ -130,7 +130,6 @@ if (import.meta.server && props.preload) { rel: 'preload', as: 'image', imagesrcset: firstSource.srcset, - nonce: props.nonce, ...(typeof props.preload !== 'boolean' && props.preload?.fetchPriority ? { fetchpriority: props.preload.fetchPriority } : {}), diff --git a/src/runtime/utils/props.ts b/src/runtime/utils/props.ts index dee657590..df8e52577 100644 --- a/src/runtime/utils/props.ts +++ b/src/runtime/utils/props.ts @@ -28,9 +28,6 @@ export interface BaseImageProps width?: string | number height?: string | number crossorigin?: 'anonymous' | 'use-credentials' | boolean - - // csp - nonce?: string } export const useImageProps = (props: BaseImageProps) => { @@ -45,7 +42,6 @@ export const useImageProps = (p width: parseSize(props.width), height: parseSize(props.height), crossorigin: props.crossorigin === true ? 'anonymous' : props.crossorigin || undefined, - nonce: props.nonce, })) const imageModifiers = computed(() => { diff --git a/test/nuxt/image.test.ts b/test/nuxt/image.test.ts index 3da837c58..96b5bb24e 100644 --- a/test/nuxt/image.test.ts +++ b/test/nuxt/image.test.ts @@ -144,23 +144,11 @@ describe('Renders simple image', () => { expect(img.html()).toMatchInlineSnapshot(`""`) }) - it('with nonce', () => { - const img = mountImage({ - src: '/image.png', - width: 300, - height: 400, - nonce: 'stub-nonce', - }) - const domNonce = img.element.getAttribute('nonce') - expect(domNonce).toBe('stub-nonce') - }) - it('can access imgEl underlying img HTMLImageElement', () => { const img = mountImage({ src: '/image.png', width: 300, height: 400, - nonce: 'stub-nonce', }) expect(img.getCurrentComponent().exposed?.imgEl).toBeDefined() expect(img.getCurrentComponent().exposed?.imgEl.value).toBeInstanceOf(HTMLImageElement) diff --git a/test/unit/bundle.test.ts b/test/unit/bundle.test.ts index b453eb73d..8d14f48f7 100644 --- a/test/unit/bundle.test.ts +++ b/test/unit/bundle.test.ts @@ -22,7 +22,7 @@ describe.skipIf(process.env.ECOSYSTEM_CI || isWindows)('nuxt image bundle size', }), ]) - expect(roundToKilobytes(withImage.totalBytes - withoutImage.totalBytes)).toMatchInlineSnapshot(`"12.6k"`) + expect(roundToKilobytes(withImage.totalBytes - withoutImage.totalBytes)).toMatchInlineSnapshot(`"12.5k"`) }) })