From a0c62611abd3b6179eff56342b9c9f4e639b1da2 Mon Sep 17 00:00:00 2001 From: Mike Samuel Date: Wed, 3 Apr 2019 12:12:06 -0400 Subject: [PATCH] Normative: Provide source text to HostEnsureCanCompileStrings This is a continuation of Mike Samuel's work in #1498. Due to #2670, this change can be made simpler than it previously was. This change provides the source text to be evaluated, and the grammar symbol that should be used to parse it, to the host hook HostEnsureCanCompileStrings. One example of where this is needed is for allowing a Content Security Policy to provide hashes for code executed via `eval()` or `new Function()`: https://github.com/w3c/webappsec-csp/issues/623 This is useful on its own, but has come up again in the topic of ShadowRealm-HTML integration. In a ShadowRealm you can either execute code asynchronously, with ShadowRealm.p.importValue, or synchronously, with ShadowRealm.p.evaluate. Because the latter uses `eval()` inside the ShadowRealm, it's subject to CSP rules, so the only CSP policy that will let you execute synchronously in the realm is `unsafe-eval`. The original purpose of #1498 was to support Trusted Types, which is still a goal of this PR. This is a separate needs-consensus PR, rather than being part of the ShadowRealm proposal, because it's useful independently of ShadowRealm, and also ShadowRealm would go forward regardless of whether this goes forward. Prior art: https://github.com/tc39/proposal-dynamic-code-brand-checks Co-authored-by: Philip Chimento --- spec.html | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 504dbfdee8b..33e97d1a684 100644 --- a/spec.html +++ b/spec.html @@ -28902,7 +28902,7 @@

1. If _x_ is not a String, return _x_. 1. Let _evalRealm_ be the current Realm Record. 1. NOTE: In the case of a direct eval, _evalRealm_ is the realm of both the caller of `eval` and of the `eval` function itself. - 1. Perform ? HostEnsureCanCompileStrings(_evalRealm_). + 1. Perform ? HostEnsureCanCompileStrings(_evalRealm_, _direct_, _x_). 1. Let _inFunction_ be *false*. 1. Let _inMethod_ be *false*. 1. Let _inDerivedConstructor_ be *false*. @@ -28965,12 +28965,18 @@

HostEnsureCanCompileStrings ( _calleeRealm_: a Realm Record, + optional _direct_: a Boolean, + optional _bodyText_: an ECMAScript language value, ): either a normal completion containing ~unused~ or a throw completion

description
It allows host environments to block certain ECMAScript functions which allow developers to interpret and evaluate strings as ECMAScript code.
+

+ If _bodyText_ is present, or _direct_ signifying whether the evaluation is a direct eval, the host environment may base its decision on their values. + Implementations of HostEnsureCanCompileStrings should not coerce _bodyText_ to a string, since callers will do that later, and HostEnsureCanCompileStrings must not base security decisions on both coercions producing the same string. +

The default implementation of HostEnsureCanCompileStrings is to return NormalCompletion(~unused~).

@@ -30158,7 +30164,10 @@

1. Let _currentRealm_ be the current Realm Record. - 1. Perform ? HostEnsureCanCompileStrings(_currentRealm_). + 1. If _parameterArgs_ is empty, then + 1. Perform ? HostEnsureCanCompileStrings(_currentRealm_, *false*, _bodyArg_). + 1. Else, + 1. Perform ? HostEnsureCanCompileStrings(_currentRealm_). 1. If _newTarget_ is *undefined*, set _newTarget_ to _constructor_. 1. If _kind_ is ~normal~, then 1. Let _prefix_ be *"function"*.