Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the eval()-related functions to be avoided when CSP is enabled?

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

like image 616
Ivan Aksamentov - Drop Avatar asked Sep 30 '18 01:09

Ivan Aksamentov - Drop


People also ask

What is unsafe eval in CSP?

'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.

Why should you avoid JavaScript eval function when possible?

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!

What can you do with the eval function?

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.

How do I fix the content security policy of your site blocks the use of eval in JavaScript?

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.


1 Answers

Mozilla docs on CSP, lists "eval() and similar methods" as possible offenders:

[…] 'unsafe-eval' Allows the use of eval() 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() or execScript(), 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.

Bonus

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.

like image 72
Ivan Aksamentov - Drop Avatar answered Nov 15 '22 00:11

Ivan Aksamentov - Drop