-
Notifications
You must be signed in to change notification settings - Fork 74
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
Clarify interaction between unsafe-eval and TrustedScript. #143
Comments
These are interesting questions! I guess it would be less of a problem if trusted-types would be capable of guarding eval independently of CSP.
|
Yeah. I think the core ambiguity is, with TT there's no difference between
It seems clear to me that the presence of TT eval guards unambiguously means
Litmus test: backwards compatibilityAdding Trusted-Types to the Content-Security-Policy header with a default policy that blesses no script values and with no explicit Litmus test: Explicit trust decisions respectedA Content-Security-Policy header with Trusted-Types and without unsafe-eval should allow If those two litmus tests make sense, that leads to the following flow for %eval%(x)
before proceeding with the permissions check. Then we'd have to define HostEnsureCanCompileStrings(calleeRealm, x) to do the following:
That leads to the following interpretation of unsafe-eval: The absence of unsafe-eval means |
To dumb this down a bit: are you saying that a document with a CSP which bans |
@arturjanc, Sorry for the overlong writeup.
Yes, but with one wrinkle. When This would allow: //// Header content: Trusted-Types "default"
//// Sensitive setup code
TrustedTypes.createPolicy('default', {
createScript(x) {
if (x === 'return this;') { return x; }
throw new Error(x);
}
});
//// Non-sensitive legacy application code
const globalObject = new Function('return this;')(); |
One major problem is that this won't work with the polyfill - in browsers that don't support TT but do support CSP (90% of current browsers), the eval can't be run, and no amount of polyfilling will fix that. Therefore, devs won't be able to use eval with TT unless they start sending 'unsafe-inline' - which depending on how far back browsers they need to support, could mean they send that flag for the next ten years, their systems less safe instead of more. |
@Sora2455 It's true that direct function functionPolyfill(...args) {
// Load code via DOM manipulation with <script>
}
functionPolyfill.prototype = Function.prototype;
Function = functionPolyfill;
// Do the same thing with Function.prototype.constructor that the realms polyfill does. Previously discussed at #120 |
I'm not sure I understand this. TT have that capability. The only interaction between TT and CSP for now is the same header used for the delivery of the enforcement policies.
or
|
I don't think that's required for backwards compatibility since pre-TT programs do not create TrustedScript values. That was the idea behind:
|
What I meant was that we should not relax the CSP restrictions. The issue is you can create policies (and types through them) even without a TT header, so that would allow the authors to call |
@koto, It sounds like you're agreeing with:
What about if I want to write a CSP policy so that:
Given that the polyfill will not support direct eval, it sounds like this case requires serving different headers to different browsers depending on their level of TT support so that
I thought in the absence of any grants, createPolicy is closed. I wonder whether there's a happy middle-ground:
That's not pithy and it means that code paths that use eval with TrustedScript are not the most field tested. |
If we can get it into CSP spec - sure, but I'm not sure CSP editors would like this extra complexity (given that this behavior is defined in a context of two separate directives). |
Actually, @arturjanc reminds that 'unsafe-eval' only kicks in for strings (at least in Chrome): https://jsbin.com/qehejuvido/edit?html,output which would elegantly allow us to enable eval(TrustedScript) without needing However, Chrome's behavior does not conform to spec: https://tc39.github.io/ecma262/#sec-eval-x and indeed, Firefox blocks that eval :/ |
Heh, I just found tc39/ecma262#1495 which describes this neatly :) |
I should also note that the |
|
@koto But those frameworks currently can't use CSP and eval together - and won't until TT is ubiquitous. That means that they have no find 'no-eval' solutions for the CSP-supporting non-TT supporting browsers, and once that's done there's no point re-enabling eval. |
Not quite. Developing a non-eval based solution is sometimes quite complex, and the only real gain is being "CSP with no unsafe-eval" compliance. What we're seeing is that this gain is not big enough to trigger the change. Adding TT-support is, ot the other hand, trivial, and backwards-compatible - adopting that gives one a TT compliance and "CSP with no-unsafe-eval in TT-supporting browsers" compliance, with is already a lot. The application could then ship |
Yeah, the consensus is that even though Firefox is correct, that difference is due to a spec bug. I am prepping https://mikesamuel.github.io/eval-in-order/ as a needs_consensus fix which would require Firefox to become consistent with Chrome in this regard.
|
@Sora2455 said
Yes, there are better alternatives to these patterns but they appear deep in widely used libraries. I worry that upgrading dependencies to newer versions of these libraries would require the kind of multi-level coordination that might prevent any one party from adopting TT+CSP in large systems. |
I'd like to explore this as an option, and it's probably better to start sooner than later. |
That would be https://github.com/w3c/webappsec-csp/. @mikewest is the editor. |
Ok. I think he's on vacation. I'll try to wrangle 10 minutes FTF. |
This reworks how `new Function(source)` and `eval(source)` are checked against a CSP and Trusted Types policy. It trusts TrustedScript when the relevant CSP policies and TrustedType configurations agree on whether to enforce and the TrustedType configuration places limits on policy creation. It also changes the previous language to use *calleeRealm* instead of *callerRealm* for consistency with other sinks. > ```js > let f = new self.top.Function(source); > ``` > In this case, the *callerRealm*'s Window is `self` and the > *calleeRealm*'s Window is `self.top`. > The Trusted Types portion of this algorithm uses *calleeRealm* > for consistency with other sinks. > ```js > // Assigning a string to another Realm's DOM sink uses that > // Realm's default policy. > self.top.body.innerHTML = 'Hello, World!'; > // Using another Realm's builtin Function constructor should > // analogously use that > // Realm's default policy. > new self.top.Function('alert(1)')() > ``` It also makes recent versions of `bikeshed` run without warnings. Fixes w3c#143 Issue w3c#144
This reworks how `new Function(source)` and `eval(source)` are checked against a CSP and Trusted Types policy. It trusts TrustedScript when the relevant CSP policies and TrustedType configurations agree on whether to enforce and the TrustedType configuration places limits on policy creation. It also changes the previous language to use *calleeRealm* instead of *callerRealm* for consistency with other sinks. > ```js > let f = new self.top.Function(source); > ``` > In this case, the *callerRealm*'s Window is `self` and the > *calleeRealm*'s Window is `self.top`. > The Trusted Types portion of this algorithm uses *calleeRealm* > for consistency with other sinks. > ```js > // Assigning a string to another Realm's DOM sink uses that > // Realm's default policy. > self.top.body.innerHTML = 'Hello, World!'; > // Using another Realm's builtin Function constructor should > // analogously use that > // Realm's default policy. > new self.top.Function('alert(1)')() > ``` It also makes recent versions of `bikeshed` run without warnings. Fixes w3c#143 Issue w3c#144
I've reopened this and #221 to continue this discussion around 'unsafe-eval', trusted types and the potential for a new script-src value. |
@lweichselbaum @koto
Per https://twitter.com/we1x/status/1113340867409076224 since TT with
eval
/Function
guards provides similar protection to CSP without unsafe eval, maybe it's worth clarifying how an application might provide degraded service when TT is not available but take advantage of TT where it is.Should a CSP policy without
unsafe-eval
preventeval(myTrustedScriptValue)
?I'm leaning no since
unsafe-eval
in a CSP header can't be contingent on trusted-types being supported.If
unsafe-eval
is present, does trusted-types guardeval(x)
/Function(x)
/import(...)
at all?Similarly for
wasm-unsafe-eval
?The text was updated successfully, but these errors were encountered: