Closed littledan closed 5 years ago
We should definitely document that.
Does the below resonate?
TT is interested in strengthening arguments like:
We trust the author of TrustedHTML
foo
to mark "foo" as trusted because we trust them to write HTML that runs in the current realm.
More generally,
We trust the author of x to write code that runs in the current realm so it's safe to use f(x, ...) to ...
Most realms that can interact are probably in the same origin, but if frozen realms succeeds in carving out a niche for untrusted code to run alongside trusted realms it may not.
<iframe>
s are one of the most common cases where realms interact. One frame's DOM content is separate from others in the same origin unless JS code goes out of its way to introduce them.
@koto @xtofian Thoughts?
It's not so hard for same-origin iframes to find each other, but at the same time, if they are the same origin, I am not sure what sense it makes to keep them separate. So I don't understand the purpose of returning false for this case.
I believe we want to assert that a template literal object was part of the js code that is running in a given realm, and not one that was created elsewhere, e.g. in a different frame. That, for example, allows us define a runtime enforcement that's closer to what we can verify statically (e.g. if a document includes a single script that passed linter/compiler checks).
Why is enforcement matching static verification a goal? I'd imagine that static verification is somewhat complementary to what this proposal achieves.
I'd be curious to learn more about how this relates to web platform security in a more broad way. To what extent are we trying to defend against same-origin frames? cc @mkwst
A cross-realm slot check would be most consistent with the language precedent.
If you also want to check same-realm, then because it’s frozen, you can use instanceof Array.
@ljharb
Thanks. I hadn't thought of that.
I now agree that there's no need to limit w.r.t. realm, and making a realm agnostic version could be more generally useful.
// Use case realm agnostic
const trustedRealmsArrays = new Set([Array.prototype, ...otherRealmsArrayProtos]);
function sensitiveTag(staticBits, ...dynamicBits) {
if (!Array.isTempalteObject(staticBits) && trustedRealmsArray.has(Object.getPrototypeOf(staticBits))) {
throw new Error(...);
}
...
}
Unless anyone objects, I'll draft a realm agnostic version of the abstraction with a non-normative note about the Realminess and instanceof Array
trick.
Not sure what you're getting at with instanceof Array
; the semantics are still a bit different due to @@hasInstance
.
@littledan yes but on an object that passes the cross-realm brand check, it will be a frozen array, with no Symbol.hasInstance
, so const isSameRealmTemplateObject = isTemplateObject(obj) && obj instanceof Array
will be reliable.
OK. I'm not sure how that's relevant to @koto 's earlier point (but I also don't quite understand that argument).
I believe we want to assert that a template literal object was part of the js code that is running in a given realm, and not one that was created elsewhere,
That's precisely what my code snippet above asserts, without needing to violate precedent by having a same-realm slot check.
Ok. So instead of having an IsTemplateObject abstraction that mirrors GetTemplateObject, I'm going to modify GetTemplateObject somewhere between
and
"frozen"
).to add a step like
true
.and then the IsTemplateObject abstraction would just check that there is such a property and its value is true.
I would recommend instead creating the template with the internal slot, and leaving it as undefined, as I did in https://github.com/tc39/ecma262/pull/1350
It seems much cleaner to me to have a slot with a value that’s checked, then to pivot on the mere presence of a slot.
In my alternate suggestion https://github.com/tc39/ecma262/pull/1350 for a proposal in this space, I suggested adding an internal slot on template objects to serve as the identifying tag. The observable difference here is that, in your spec text in this repository, a cross-Realm template will return false. Was this the intention? If so, would it make sense to document the rationale in the README?