Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unsafe-eval security error in chrome extension #105

Closed
chinchang opened this issue Aug 11, 2013 · 12 comments
Closed

unsafe-eval security error in chrome extension #105

chinchang opened this issue Aug 11, 2013 · 12 comments
Labels

Comments

@chinchang
Copy link

The error seems to be coming because of the following code:

f=Function("return this")()

Error:

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' chrome-extension-resource:".

Reduced case chrome extension: http://dl.dropboxusercontent.com/u/42214070/urijs-security-issue.crx

@rodneyrehm
Copy link
Member

I see the offending piece of code is generated through minification (Closure Compiler or UglifyJS2). This is (most likely) something I cannot fix within URI.js' source. Maybe you'll have to use the unminified code instead…

@chinchang
Copy link
Author

I see the same thing in the source as well: https://github.com/medialize/URI.js/blob/gh-pages/src/URI.js#L30

It could be changed to:

var root = (function(f){ return (function() { return this; })(); })();

@rodneyrehm
Copy link
Member

It's not that easy:

var root1 = (function(f){ return f('return this')(); })(Function);
var root2 = (function(f){ return (function() { return this; })(); })();
root1 === root2; // is false, because root2 is undefined.

Note: this is not the case if above code is run in the command line of your browser…

@rodneyrehm
Copy link
Member

Is the following also causing a SecurityError?

var root = (function(f){ return new f('return this')(); })(Function);

@chinchang
Copy link
Author

Still get the error.

About your above code:

var root1 = (function(f){ return f('return this')(); })(Function);
var root2 = (function(f){ return (function() { return this; })(); })();
root1 === root2;

Did you run it from within an IIFE and got false?

@rodneyrehm
Copy link
Member

(function(){
    var root1 = (function(f){ return f('return this')(); })(Function);
    var root2 = (function(f){ return (function() { return this; })(); })();
    root1 === root2; // is false
})();

if you run above code in the command line of your browser, you'll get true

@rodneyrehm
Copy link
Member

This problem was introduced with #84 - maybe @jasonkarns has an Idea how to circumvent this SecurityError?

@jasonkarns
Copy link
Contributor

Hmm. I don't recall Chrome throwing that error at the time I encountered that snippet. Perhaps noConflict should be backed out until there's a workaround?

I've independently come to the conclusion that noConflict-style support is probably best handled by a micro-library, rather than natively within URI.js. Maybe it's just not worth it?

@rodneyrehm
Copy link
Member

To be fair, this SecurityError is thrown for Chrome Extensions - not the regular browser context.

I don't mind noConflict(). I'd like to keep it. After all, URI might eventually used by something native…

Accessing the global context seems to be the problem - is there no other way to safely get to it?

@jasonkarns
Copy link
Contributor

So the purpose of noConflict is to allow users, when in a browser context, to safely include URI.js while controlling the impact it has on the global namespace. This is only a concern for non-module users. URI.js uses the UMD module definition pattern such that AMD or CommonJS users are already in control of the namespace footprint of URI.js. The UMD pattern already has access to the root object at the time the factory function is invoked. A possible solution is to modify the factory function to accept the root object as the last parameter. Or alternatively, execute the factory function in the context of the root object, thus giving the factory function access to the same root object as the UMD wrapper. Both solutions would remove the need for the pseudo-eval entirely.

@jasonkarns
Copy link
Contributor

I just pushed up two branches to illustrate the two alternatives mentioned above. Neither has been tested.

A possible solution is to modify the factory function to accept the root object as the last parameter.

Quick and dirty implementation compared with master: jasonkarns/URI.js@medialize:master...root-factory-signature

Or alternatively, execute the factory function in the context of the root object, thus giving the factory function access to the same root object as the UMD wrapper.

Compared with master jasonkarns/URI.js@medialize:master...root-factory-context

@rodneyrehm
Copy link
Member

The issue is fixed in master and will be included in the next release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants