next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Content Security Policy failure caused by is-generator-function dependency

Open feross opened this issue 3 years ago • 5 comments

What version of Next.js are you using?

10.1.2

What version of Node.js are you using?

15.12.0

What browser are you using?

Firefox

What operating system are you using?

macOS

How are you deploying your application?

Other

Describe the Bug

"Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”)."

Caused by is-generator-function.

Output of npm why is-generator-function:

[email protected]
node_modules/is-generator-function
  is-generator-function@"^1.0.7" from [email protected]
  node_modules/util
    util@"^0.12.0" from [email protected]
    node_modules/assert
      assert@"2.0.0" from [email protected]
      node_modules/next
        next@"^10.1.2" from the root project
    util@"0.12.3" from [email protected]
    node_modules/next
      next@"^10.1.2" from the root project

Expected Behavior

No CSP warnings.

To Reproduce

When this code is run by next.js in Firefox, the warnings appears:

	try {
		return Function('return function*() {}')();
	} catch (e) {
	}

It isn't clear what causes this to run, but you can see it in action in our app https://wormhole.app

feross avatar Mar 31 '21 17:03 feross

Same here in Google Chrome (Version 100.0.4896.75 (Build officiel) (x86_64)) by following the https://github.com/vercel/next.js/tree/canary/examples/with-strict-csp exemple.

I'm getting this error :

Capture d’écran 2022-04-07 à 23 55 07

Versions : "next": "^12.1.4",

clement-faure avatar Apr 07 '22 21:04 clement-faure

There's no way to avoid this, unfortunately, because generator function syntax has to be done with eval, or else it would hard-break older engines/browsers.

You could probably write a bundler transform, when you know that all the targets support the syntax natively, to replace that line in is-generator-function with the direct syntax.

ljharb avatar Apr 07 '22 22:04 ljharb

Thank you for your answer. Unfortunately, i'm not able to reproduce the error message when cloning the https://github.com/vercel/next.js/tree/canary/examples/with-strict-csp, so i shouldn't have this message... I'll try to investigate on my side regarding my csp configuration...

clement-faure avatar Apr 08 '22 08:04 clement-faure

Just wanted to hop in and say I am running into the same issue... @clement-faure I am also using something similar to your approach but still running into the issue. Here's a sample of my CSP:

function createScriptSourceCspOption(scriptSource: string) {
  if (Environment.isProduction) {
    const hash = crypto.createHash('sha256');
    hash.update(scriptSource);
    return `'strict-dynamic' 'sha256-${hash.digest('base64')}'`;
  }
  return `'self' 'unsafe-eval'`;
}

export default class MyDocument extends Document {
  render() {
    const cspScriptOption = createScriptSourceCspOption(
      NextScript.getInlineScriptSource(this.props)
    );
    const csp = `
      font-src https://rsms.me;
      img-src 'self' data: https://s3.amazonaws.com/photos http://www.w3.org/2000/svg;
      media-src 'none';
      object-src 'none';
      script-src ${cspScriptOption} 'unsafe-inline' http: https:;
      script-src-elem 'self' http://cdnjs.cloudflare.com;
      worker-src 'self' blob: http://cdnjs.cloudflare.com;
      style-src 'self' https://rsms.me 'unsafe-inline';
    `;

    return (
      <Html>
        <Head>
          <meta httpEquiv="Content-Security-Policy" content={csp} />
          <link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
          <link rel="icon" type="image/x-icon" href="/icons/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Should I allow unsafe-eval until this issue is addressed? Or is there a way to scope the unsafe-eval to just that util.js file?

crice88 avatar Apr 27 '22 18:04 crice88

Should this issue maybe be renamed? This is still an issue but is not in this dependency as far as I can see. (It's in assert and util right now.)

I'm also thinking there should be a disclaimer about this in the documentation. At least as long as this is an issue. Right now the example there doesn't work at all and will give you errors.

Kolombiken avatar Nov 09 '22 15:11 Kolombiken

I'd expect such a disclaimer in the CSP documentation - disabling eval on the page is highly likely to break third-party code, and as such, should be carefully considered before restricting it.

ljharb avatar Nov 09 '22 19:11 ljharb

I'd expect such a disclaimer in the CSP documentation - disabling eval on the page is highly likely to break third-party code, and as such, should be carefully considered before restricting it.

Improving documentation to avoid surprises is good but it does not remove the security risk inherent in allowing unsafe-eval. Some of us care a lot about protecting our users from the consequences of XSS vulnerabilities.

ramosbugs avatar Nov 09 '22 22:11 ramosbugs

I totally agree, but not all eval is unsafe, unfortunately, which is the case here.

ljharb avatar Nov 09 '22 23:11 ljharb

I agree with you @ramosbugs. My point was that having an example in the documentation that will likely cause an error without any disclaimer will just cause confusion. And might result in people allowing more things than needed in their CSP making their application vulnerable.

As far as I have tested it's possible to have pages without getting the error. But it's very likely that you will get an error. I'm not sure right now what the exact trigger is. Such information would also be helpful. E.g. if you are using feature x you need to enable unsafe-eval or your application will not work properly.

Kolombiken avatar Nov 10 '22 08:11 Kolombiken

That code tests for the availability of generator functions (all major browsers after IE11), but triggers a CSP eval error. It was introduced in version 12.0.8, perhaps by commit https://github.com/vercel/next.js/commit/3667eba38559e5ccb810bade4779cda3649f1413. This issue is still present in 13.1.2. I also tried to figure out what the trigger is, since it doesn't happen on all pages, but haven't found any logic yet.

Can't we drop the regenerator polyfill (or at least give the option to do so?). IE11 is not in the list of supported browsers for Next.

mauritsl avatar Feb 01 '23 15:02 mauritsl

This is very bad-practice. unsafe-eval should never be required. I run into this today as well. Can we prioritize it please. I'm on Next 14.1.0.

StarpTech avatar Mar 16 '24 20:03 StarpTech

@StarpTech https://github.com/vercel/next.js/issues/23587#issuecomment-1309547758 eval using Function on a string literal is simply not unsafe.

ljharb avatar Mar 16 '24 20:03 ljharb

But we can't whitelist this in the CSP policy. Using unsafe-eval will be applied to all trusted origins.

StarpTech avatar Mar 16 '24 21:03 StarpTech