-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Right now the only way to allow eval
(or the equivalent new Function
) is by using the unsafe-eval
policy. This policy should be used as little as possible, because it allows *any* usage of eval/Function rather than just a list of trusted ones.
One use case for eval
is feature detection. When testing for new syntax you can wrap it in new Function
and check whether it can be parsed or not. In this case strings are static, and so it's easy to hash them ahead of time and provide the has as part of the CSP:
let supportsDecorators = false;
try {
new Function("@dec class A {}"); // allowed
supportsDecorators = true;
} catch {}
import(supportsDecorators ? "./source.js" : "./transpiled.js");
</script>
another use case comes from the ShadowRealms TC39 proposal, that was recently demoted from Stage 3 to Stage 2 because the integration with the web platform is not fully flashed out yet.
That proposal exposes realms with a restricted interface to JavaScript, and there are two ways to run code in them:
- synchronously, with a
ShadowRealm.prototype.evaluate(code: string)
method - asynchronously, with a
ShadowRealm.prototype.importValue(moduleURL: string)
method
.evaluate
basically runs eval()
inside the shadow realm, and for this reason it should follow normal CSP rules. However, under the existing policies this means that the only way to synchronously evaluate code in shadow realms is by using unsafe-eval
.
How do you feel about extending hash-based policies to also support eval
/new Function
? This would make it possible to write the example above as follows:
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'sha256-c25cd64187ae9eb96a23e52e9f55dfc4cf0fbf19f60885eca8abb94c9644a72a'">
<script>
let supportsDecorators = false;
try {
new Function("@dec class A {}"); // allowed
supportsDecorators = true;
} catch {}
import(supportsDecorators ? "./source.js" : "./transpiled.js");
new Function(someOtherString); // still disallowed!
</script>
and would work similarly with shadow realms.
An alternative, if we don't want to change the existing unsafe-hashes
behavior, could be to introduce a new unsafe-eval-hashes
policy.
(cc @ptomato, who is working with me on this)