I bundle my React app with Webpack and add Content Security Policy (CSP) headers (in particular, not allowing unsafe-eval
in script-src
). Of course, I make sure my final bundle and chunks do not contain eval()
. However, latest Firefox-dev 63.0b10 still refuses to load the main chunk with the following error:
Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src”). Source: call to eval() or related function blocked by CSP.
Well, but I don't have eval()
in my bundle.
What those "related functions" could be?
P.S. This is a self-answered question, but feel free to extend
'unsafe-eval' allows the application to use the eval() JavaScript function. This reduces the protection against certain types of DOM-based XSS bugs, but makes it easier to adopt CSP. If your application doesn't use eval() , you can remove this keyword and have a safer policy.
Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!
Eval function is mostly used in situations or applications which need to evaluate mathematical expressions. Also if the user wants to evaluate the string into code then can use eval function, because eval function evaluates the string expression and returns the integer as a result.
The Content Security Policy (CSP) prevents the evaluation of arbitrary strings as JavaScript to make it more difficult for an attacker to inject unauthorized code on your site. To solve this issue, avoid using eval() , new Function() , setTimeout([string], ...) and setInterval([string], ...) for evaluating strings.
Mozilla docs on CSP, lists "eval()
and similar methods" as possible offenders:
[…]
'unsafe-eval'
Allows the use ofeval()
and similar methods for creating code from strings. […]
CSP3 specification § 1.2.1, mentions "eval()
and similar constructs":
Mitigate the risk of content-injection attacks by giving developers fairly granular control over […] Dynamic code execution (via
eval()
and similar constructs) […]
But the final answer is further in CSP3 spec, in § 6.1.10.4:
The following JavaScript execution sinks are gated on the "
unsafe-eval
" source expression:
eval()
Function()
setTimeout()
with an initial argument which is not callable.setInterval()
with an initial argument which is not callable.Note: If a user agent implements non-standard sinks like
setImmediate()
orexecScript()
, they SHOULD also be gated on "unsafe-eval
".
So, for CSP purposes, the complete list of "dynamic code execution constructs", eval()
's "similar methods", "related functions", "similar constructs" is:
eval()
Function() // typically new Function()
setTimeout() // with non-callable argument
setInterval() // with non-callable argument
setImmediate()
execScript()
In my case, I found a few new Function(...)
fragments in the bundle and now figuring out how to prevent them from appearing.
If you take grepl
or a similar grep
-like tool that finds string matches and prints surrounding context in char-by-char basis (rather than line-by-line, as normal grep
) you can use the following command to find "dynamic code execution constructs" in all of the files of your bundled (minified and code-split) app:
find "<build_dir>" -type f -iname "*.js" -exec grepl -k 512 -H "(eval|Function)(\s|\t)*\(" '{}' \;
Alternatively, you could turn off JS minifier (e.g. UglifyJS) and inspect your build with normal grep
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With