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

Error: call to Function() blocked by CSP #401

Closed
cr opened this Issue Jul 3, 2015 · 8 comments

Comments

Projects
None yet
2 participants
@cr

cr commented Jul 3, 2015

math.js 1.7.0 fails with Error: call to Function() blocked by CSP in line 14065 when a CSP is applied:

var factory = new Function ('defs', factoryCode);

This may not be the only code that fails under a CSP. Adding the 'unsafe-eval' CSP attribute doesn't prevent this (in Firefox).

It should be possible to use math.js in a CSP-secured environment.

@josdejong

This comment has been minimized.

Owner

josdejong commented Jul 3, 2015

Thanks for bringing this up. The expression parser of math.js compiles JS code (using new Function(...)) to drastically improve performance of evaluating expressions (at least 10x faster). It would be too bad to not use this code compilation just to make life a bit easier for webapps using CSP.

CSP has various ways to mark a script as safe: source white list, nonce, hash. Wouldn't it be enough to use of one of these options to mark the code of math.js as safe?

@cr

This comment has been minimized.

cr commented Jul 6, 2015

There is no way to select local scripts individually to differentiate the CSP, so the only choice is to have 'unsafe-eval' for everyone. An option to skip compilation would allow a security/performance trade-off. Would that be hard to implement?

@josdejong

This comment has been minimized.

Owner

josdejong commented Jul 7, 2015

Creating a version of math.js not using compilation of expressions using eval will require to implement (and maintain!) two versions of compile/eval which share some similarity but are quite different, and distributing two versions of math.js. It's not a matter of disabling a specific feature of the code or something like that. I will give it some more thought but I don't think there is a nice solution for this allowing both cases without complicating the codebase.

I'm not familiar with CSP, I suppose you more know about it than I do.The docs I saw looked like it's pretty versatile. Did you for example ask about this on stackoverflow whether it's possible to selectively apply 'unsafe-eval'?

I understand you want to tighten the policy as good as possible, but when you only allow white-listed scripts, is it really a problem to allow all of them to use unsafe-eval?

@cr

This comment has been minimized.

cr commented Jul 7, 2015

The CSP documentation leaves no doubt that the only selector for local sources is 'self', and a colleague within Mozilla security pointed out the reason to me: Due to the dynamic nature of JavaScript and the DOM, the browser currently can't reliably pinpoint calls to an individual file source, just to their domain.

I completely sympathize that maintaining two branches for this is unfeasible. I was just hoping that disabling parser compilation at runtime was easier than you outlined. So for now I'm content with having delivered food for thought.

@josdejong

This comment has been minimized.

Owner

josdejong commented Jul 8, 2015

Ah makes sense. In that case we can't do much. I have a (vage) idea on a possible replacement for the current compilation step without using new Function() or eval(), I will do an experiment with to see if that would perform, but this will not be on very short term.

@josdejong

This comment has been minimized.

Owner

josdejong commented Sep 21, 2015

Since math.js v2, the library heavily depends on dynamically compiling functions using new Function() (by means of typed-function. It's much harder now to create a version of the library not using eval like functionality, that would require to create a version of typed-function which doesn't use dynamic compilation.

@josdejong josdejong closed this Oct 29, 2015

@josdejong

This comment has been minimized.

Owner

josdejong commented Feb 21, 2018

@cr It has been a while, but I have some good news. Hadn't expected it to be possible to get there, but the upcoming mathjs v4.0.0 does not use eval under the hood anymore. This means that it should be possible to use it in CSP-secured environments :D

v4.0.0 isn't yet released but you can try the release candidate, see #682 (comment) for details.

@cr

This comment has been minimized.

cr commented Mar 2, 2018

Congrats, @josdejong, that's a major accomplishment for the project! 👍

And thanks for letting me know. I'll definitely check it out for the next RPN calculator project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment