JavaScript eval function and Content Security Policy

By Akbar

I have been getting warnings for my two of the Basecampe Extensions for the manifest version 1, and need to upgrade those to version 2. However, when working on this upgrade, I found that upgrade was not as simple, as I thought at first.

The biggest problem for me was the new Content Security Policy of Chrome Extension, and to make my application compliant with this, I have to do a lot of code changes here and there in the extensions.

Most of them was simple, though tedious, to integrate. However, I was stuck on one issue and that’s new security policy doesn’t allow the javascript “eval” function. I have been using this in past for evaluating the JSON, checking dynamic global variables and executing dynamic code from the server.

While, I can understand that it’s pretty dangerous and vulnerable to attacks, I have to use it one way or the other. Fortunately, there are some workarounds available. For example, one of the most widely use of the eval by me is to evaluate if a particular event has occurred or something is loaded:

eval(" result = " + customJavascriptCode)

If you don’t want to use the eval (or are blocked by some security policy like I was), then one simple workaround for this is by help of javascript Anonymous functions like:

var result = ( new Function( 'return ' + customJavascriptCode) )();

Now, I think this is as unsecure as the eval function, and in fact, this gets blocked by Chrome Extension. So the better workaround is to instead of passing the string to evaluate or make anonymous functions, simply pass the anonymous functions and then let the evaluation script simply execute them. So here is another round of changes which actually work in Chrome extension too:

// Instead of passing the string to evaluate, pass anonymous function evaluate
var result = getResult( function() { return javaScriptVariableToCheck };)
// The target function can then execute that function to generate, process and return the
// results.
function getResult(func) {return func(); }

In worst case, if you only get the JavaScript as a string (may be from some third party) and still want to evaluate the results, the one (though bad in terms of security) is to pass create send this JavaScript as string to a HTTP server which simply echo it back, and then you can use that server file in the Script src tag. The following thread discuss this option in bit more detail:

One the side note, if you have been using the eval to evaluate JSON in past (like me), the I found that there is a better workaround for this, and that’s most of the latest browser, including Chrome 3.0+ support JSON object which helps you easily achieve this goal. Here is a sample of this which works fine in Chrome:

JSON.parse("{ "firstName": "John", "lastName": "Smith" }")

Tags: , ,