mocha: content_security_policy - EvalError: Refused to evaluate a string
The problem: I’ve had to add the following line to a chrome extension manifest file in order for the latest version of Mocha to work: "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';",
Without this line, mocha scripts fails to run with the following error:
mocha.js:13165 Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
at Function (<anonymous>)
at mocha.js:13165
at createCommonjsModule (mocha.js:16)
at mocha.js:12456
at mocha.js:4
at mocha.js:5
The mentioned workaround was found here: https://stackoverflow.com/a/48047578 but ideally we don’t want to meddle with the content_security_policy
The error seems related to the following piece of code in mocha.js
:
// In sloppy mode, unbound `this` refers to the global object, fallback to
// Function constructor if we're in global strict mode. That is sadly a form
// of indirect eval which violates Content Security Policy.
function () {
return this;
}() || Function("return this")());
This looks like a regression in the newer versions of Mocha as this issue doesn’t occur after downgrading to Mocha 8.1.3 .
What I’ve tried:
Experimented with different devtool
settings including "cheap-module-source-map"
and false
How I’m running Mocha: Slightly differently because of testing a chrome extension with a specific page. But the core idea works in other projects and shouldn’t be related to the described error.
mocha.setup("bdd");
mocha.timeout(8000);
// set up all the relevant tests
mocha.run()
How I’m working around this at the moment: Downgraded to Mocha 8.1.3
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 2
- Comments: 17 (15 by maintainers)
I don’t know the root cause, but we introduced it in https://github.com/mochajs/mocha/commit/12db9dbc9dd3b0ec31c182d0e41a6ec615735401 after I tracked it via
git bisect
.@goatonabicycle @snoack thanks for your support. I’m willing to solve this issue, but you have to take the lead. I lack the knowledge and will have to ask questions.
Unfortunately we haven’t dropped the support of IE11. But we started using modern Javascript and transpiling since Mocha v8.1.0. So I’m surprised that v8.1.3 is working as expected. Whatever we will change, Mocha has to keep supporting lovely IE11.
I’m afraid no.
This commit landed in v8.2.0, and would explain why v8.1.3 is still working. I will have to check wether we haven’t used
async/await
before.Do you have any other suggestions, please? @outsideris ?
This issue keeps us for a while from updating to any version of Mocha newer than 8.1.3, and I assume that applies to everyone who uses Mocha to test a browser extension. Right now, we could as a workaround relax the
content-security-policy
in the extension’smanifest.json
. But we don’t want to run our tests in an environment that is unnecessarily different from the production environment. Even more importantly, with manifest v3, this will no longer be an option. Consequently, if this issue is not being addressed, it means that Mocha is no longer a solution for testing browser extensions, and anyone using it for this purpose should start looking for alternatives.This weekend, probably.
Thanks @dfkaye for your feedback. @snoack your proposition sounds very promising, I will check your PR 👍 .
There seems to be another option. If we update
regenerator-runtime
to the latest version, it uses a different approach to set a variable in the global scope:This will still fail in strict mode without unsafe eval. But now we can just add
var regeneratorRuntime;
to the top of the generated code (with Rollup’soutput.intro
setting). That wayregeneratorRuntime = runtime
is no longer an implicit definition of a global variable (which fails in strict mode), but it becomes just a reassignment of an existing variable which never fails, and so the code in thecatch
block (which requires unsafe eval) is never reached.This will give us a bundle that will work both on Internet Explorer 11, and in environments that don’t allow unsafe eval.
As @goatonabicycle concluded above, the offender here is
regenerator-runtime
. Babel automatically includesregenerator-runtime
into the generated code when transpiling any generator functions orasync
functions. Since 12db9db is the first commit that made use ofasync
/await
this change caused the regression here.If it’s acceptable to drop support for Internet Explorer 11 (which is the only browser listed in
.browserslistrc
that doesn’t have native generator support), all it would take to fix this bug is telling Babel to just not transpile generator functions:Note that
async
functions will still work on browser that lack native support as long as they support generators.@juergba, what do you think?
Hello.
So, this issue was investigated with an eye on seeing how to help out or at least get some direction.
Like @outsideris mentioned, a
git bisect
shows that commit https://github.com/mochajs/mocha/commit/12db9dbc9dd3b0ec31c182d0e41a6ec615735401 does introduce the code block mentioned above (searching for “sloppy” in the build output to quickly find it)It seems like that block of code gets indirectly introduced by
regenerator-runtime
. Which seems to tie in with the global setup stuff mentioned in this release: https://github.com/mochajs/mocha/releases/tag/v8.2.0Relevant to this discussion is also this post which seems to very closely mirror this exact issue we’re experiencing.
@boneskull Sorry for the random ping but would you perhaps be able to add some insight into this?
Thank you so much!