-
Notifications
You must be signed in to change notification settings - Fork 66
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
Content Security Policy: avoid need for "unsafe-eval"? #141
Comments
Relevant references:
I am not sure you can rely on always being able to catch these type of exceptions. |
It works for me in Chrome, Firefox, Edge, Opera and Safari; and according to the references in that StackOverflow answer the CSP standard requires browsers "MUST" throw an Webpack uses the same process, though admittedly only in its templating code. |
Not quite.
That depends on the library author...
Cheers. |
citation-js depends on moo which uses unsafe evaluation for optimization. See: citation-js/citation-js#138 and no-context/moo#141
Replace use of moo.keywords(), as it uses the Function() constructor for performance. Allthough it seems safe from the regular security issues of eval(), it can cause issues with CSP directives. See no-context/moo#141 Fix #138
PR created with the suggested change. |
With apologies for the late reply:
That seems very reasonable to me! I would gladly review such a PR. My only concern is that developers using Moo may not realise that this is happening, but I don't think there's a great way to fix that. We could throw in a As far as benchmarks go, I'm afraid the JSPerf has been lost to time. If someone is able to demonstrate that the generated switch statement provides little benefit we can consider removing it, but from what you've said I don't think that is the case. |
On arm64 macOS Chrome 99. |
@nathan Do you have a link to the benchmark code? I could test it on Windows x64 too. |
Thanks for putting that together, @nathan! I agree with what you wrote elsewhere:
|
We still need our own version of this code until the library is updated to avoid eval, but the maintainers point out that using Maps is almost 10x faster. I checked for our keywords and find over a 10x improvement. Map looks to be widely supported in browsers so this ought to be simple. Still worth watching no-context/moo#141 until the library is updated.
Fixed in #173! Thanks to @jsharkey13 for writing and @nathan for reviewing 🙏 |
We use
moo.js
to parse mathematical answers provided by students in an online learning platform, to preview what they have typed. We're thus using it in-browser and are running into issues with our strict Content-Security-Policy blocking unsafe evaluation of JavsScript.moo.js
uses the unsafeFunction
constructor; apparently for speed reasons since switch-case is faster than attribute lookup (although the JSPerf link mentioned in that method no longer works for me?). Use of Function is blocked if a website uses a CSP header unless explicity enabled by usingscript-src: 'unsafe-eval'
. We would strongly like to avoid this security vulnerability, but do not want to abandon this library.At the moment we're just using a rewritten version of your
keywordTransform
method instead of the default one. Instead of using the switch-case built as a string and compiled down viaFunction
, we just use thereverseMap
object directly.i.e. replacing the line:
with
which seems to have exactly the same behaviour as the generated switch-case does, as far as I can tell.
In our use-case, with ~10 token types and 50 keywords, this seems to suffer about a 50% performance hit on using the switch-case Function version, but is still incredibly fast. Using our own version is not a particularly future-proof solution though.
It is actually possible to catch the CSP violation in a try-catch block, and alter the behaviour of the function; for example:
Would you be happy to allow this library to fall back to an object attribute lookup, iff a CSP header was blocking the Function constructor? I could provide the pull request if so.
For users not blocking Function, this has only the performance overhead of one Function object creation and one if statement, only at initialisation when calling
moo.keywords
and otherwise behavior remains as-is. For users who do use a CSP; the library will be slower, but would then still function.I would also be interested in knowing what the JSPerf example was, and how to benchmark the object attribute lookup fallback with a use-case other than ours.
The text was updated successfully, but these errors were encountered: