vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.79k stars 26.95k forks source link

CSP error when using next/image #45184

Open ennair opened 1 year ago

ennair commented 1 year ago

Verify canary release

Provide environment information

Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 21.6.0: Sun Nov 6 23:29:57 PST 2022; root:xnu-8020.240.14~1/RELEASE_ARM64_T8101 Binaries: Node: 18.12.1 npm: 9.3.1 Yarn: 3.3.1 pnpm: N/A Relevant packages: next: 13.1.5-canary.2 eslint-config-next: 13.1.4 react: 18.2.0 react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Image optimization (next/image, next/legacy/image)

Link to the code that reproduces this issue

https://github.com/ennair/next-test/tree/next-image-test

To Reproduce

  1. Checkout the project.
  2. Run yarn
  3. Run yarn build
  4. Run yarn start
  5. Open localhost:3000
  6. You will see the page loading with an image and in the console a CSP error.

Describe the Bug

When using next/image it always adds inline styling on the image. It adds: style="color:transparent". Also in case I add my own styling. Because of this, I get a CSP error. I have to add style-src 'unsafe-inline', which I do not want to add.

Expected Behavior

Next/image should not add inline styling on the image component.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

MrEmanuel commented 1 year ago

I have the same issue. I'm generating my content-security-policy (csp) header in _document (not using the new app-structure), and adding it to a meta tag, and that seems to do the trick for all scripts and styles, except for static file images in the /public folder.

I haven't applied any inline styles, but as ennair says next seem to add style="color:transparent" which triggers an error.

vzrenggamani commented 1 year ago

Same problems here, does the color:transparent could be disabled in some reason or just we need blurdDataUrl @MrEmanuel ?

basvkl commented 1 year ago

Is there an update on this? I'm running into the same thing

xecrets commented 1 year ago

Still getting color:transparent inline style when using the <Image /> component in Next.js 13.4.19, and still causing SEO validation errors. Either get rid of the inline style, or provide a css that includes the required styles and use it.

MathiasGruber commented 1 year ago

This is quite annoying when trying to enforce strict CSP. A workaround is to add style={{ color: undefined }} to the <Image /> tag

xecrets commented 1 year ago

@MathiasGruber I just tried your style={{ color: undefined }} workaround, but I can't seem to get it to work. It seems to be just ignored, and I still get style="color: transparent;" in the generated img tag.

Are you sure your workaround works, what can I be doing wrong if so?

jordanpurinton commented 11 months ago

Bump

Edit by maintainers: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

jordanpurinton commented 11 months ago

I also am experiencing this error. If we follow the CSP docs as laid out, you encounter errors in the console in prod mode when using the next image component since there is an inline style applied.

icyJoseph commented 9 months ago

This is still an issue. Though there's a workaround in Next 14.1.0, with getImageProps, and at the risk of having bad UI because of not applying the color transparent.

I wonder if there are grounds to have an API to tell Next.js to apply CSS classes instead? In a sort of, I know what I am doing, we'd tell Next.js that, these styles are found in a global CSS class, and it would have to trust that they do exist.

sneko commented 8 months ago

I found a way to use my custom style with next/image while being a minimal workaround: https://github.com/vercel/next.js/issues/61388#issuecomment-1988278891

icyJoseph commented 8 months ago

Now in 14.1.x, you can use getImageProps though, and peel out the style object if you don't want it.

sneko commented 8 months ago

Yeah, I started to make a reusable component at start, but at the end I preferred having the little style override.

For record:

// Image.tsx

import NextImage, { getImageProps } from 'next/image';
import { ComponentProps } from 'react';

export default function Image(props: ComponentProps<typeof NextImage>) {
  const { props: nextProps } = getImageProps({
    ...props,
  });

  const { style: _omit, ...delegated } = nextProps;

  return <img {...delegated} />;
}

Then use import Image from './Image'; instead of import Image from 'next/image';.

EDIT: my workaround mentioned above is more about using a custom style despite having the next/image workaround.

BrianHHough commented 7 months ago

Thank you for sharing this @sneko - this worked great for me and got me around the CSP issues I was facing! I like this reusable component approach and how it doesn't trigger the CSP error: Refused to apply inline style because it violates the following Content Security Policy directive:

Really appreciate you making this and sharing it!

KoenBrouwer commented 6 months ago

I'm facing the same issue, where the discussions about removing unsafe-inline from the Content Security Policy are driving me absolutely nuts.

@icyJoseph Now in 14.1.x, you can use getImageProps though, and peel out the style object if you don't want it.

I've (quickly) tested this today (on 14.2.1) and there doesn't seem to be any visual regression as far as I can see. However in https://github.com/vercel/next.js/discussions/45209#discussioncomment-4762949 @leerob mentions that the styles are needed for the component to work properly.

Obviously @icyJoseph's solution will omit the style tag, and in https://github.com/vercel/next.js/issues/61388#issuecomment-1988278891 @sneko's solution seems viable, but do we know if @leerob's claim that they are really necessary is valid? Why are the inline styles added in the first place? If they are needed, what breaks if they are not?

psztoch commented 5 months ago

style="color: transparent" is very bad for Svg with fill="currentColor"!

Bernardoow commented 4 months ago

Help us @leerob!!! .. can you explain why color: transparent is required ?

icyJoseph commented 4 months ago

Help us @leerob!!! .. can you explain why color: transparent is required ?

Some browsers show the alt text, while the image is loading, and that can cause CLS.

@Bernardoow I added a link to the PR that introduced that

Bernardoow commented 4 months ago

Heeeyy @icyJoseph !!

Thank you !! I'm new with NextJS and with your link I got what I was looking for.

I found where was added the color: transparent [1][2]. My solution is similar to @MathiasGruber solution but I added just an empty string. It worked to NextJS 14.2.4 and the CSP was gone.

<Image style={{color: ''}} />

[1] https://github.com/vercel/next.js/blob/30784418f8a3763273439cfd7bff133203fa8efd/packages/next/src/shared/lib/get-img-props.ts#L608C5-L608C16 [2] https://github.com/vercel/next.js/blob/30784418f8a3763273439cfd7bff133203fa8efd/packages/next/src/client/image-component.tsx#L394

Mithradatis commented 2 months ago

@MathiasGruber I just tried your style={{ color: undefined }} workaround, but I can't seem to get it to work. It seems to be just ignored, and I still get style="color: transparent;" in the generated img tag.

Are you sure your workaround works, what can I be doing wrong if so?

This workground only works in client components

styfle commented 1 week ago

Why are the inline styles added in the first place? If they are needed, what breaks if they are not?

Without inline styles, these props won't work:

And the alt prop will be visible while loading the image (see PR https://github.com/vercel/next.js/pull/39366).

If you're not using any of those props or you don't mind the missing features, you can use getImageProps as suggested above in https://github.com/vercel/next.js/issues/45184#issuecomment-1988319088

If you want to submit a PR with a more comprehensive solution, the source code is here:

https://github.com/vercel/next.js/blob/eca4c8d397ad25ff5703fa862f13e2ddae07dfd4/packages/next/src/shared/lib/get-img-props.ts#L691