Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Need to key function identities off effective script origins of both caller and object #8

Closed
bholley opened this issue Oct 20, 2015 · 24 comments

Comments

@bholley
Copy link
Collaborator

bholley commented Oct 20, 2015

Worth adding tests for this case too if they aren't there already.

@annevk
Copy link
Owner

annevk commented Oct 21, 2015

What is the effective script origin of the object (of its global object?) and why would it be necessary to use that as part of the key since the map lives on the object?

@bholley
Copy link
Collaborator Author

bholley commented Oct 21, 2015

Suppose we have Window |a| from foo.example.com and Window |b| from bar.example.com. |a| sets document.domain to 'example.com', and then grabs a reference to b.location (which appears cross-origin). Next, |b| also sets document.domain to 'example.com'. The Location object and behavior observed by the script in |a| change (to become same-origin), even though the effective script origin of |a| did not change.

In practice, Gecko clears the cache whenever either of the effective script origins change, whether or not that change causes them to become same-origin.

@annevk
Copy link
Owner

annevk commented Dec 17, 2015

Okay, so what we want to say here is that crossOriginKey is a tuple consisting of the effective script origin of this' Realm's global object and this' associated Document's effective script origin.

@domenic
Copy link
Collaborator

domenic commented Dec 17, 2015

Nit: as far as I can tell only Documents have effective script origins... I think you end up wanting "incumbent settings object's responsible document's effective script origin."

@bholley
Copy link
Collaborator Author

bholley commented Dec 17, 2015

Per previous discussion, I think we should use the current realm rather than the incumbent settings object here.

@domenic
Copy link
Collaborator

domenic commented Dec 17, 2015

@bholley in what cases would that be different? Since settings objects are the only place to get an effective script origin right now, I think you would end up having to say the same thing in more words (e.g. "the settings object whose realm execution context is the top-level execution context of the current realm", which is just "incumbent settings object")

@bholley
Copy link
Collaborator Author

bholley commented Dec 17, 2015

They differ in the case of invoking a non-scripted cross-realm same-origin function. The current realm is that of the function, whereas the incumbent script represents that of the caller.

I've been pushing for the removal of incumbent script, because it makes things unnecessarily complicated. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=26603

@domenic
Copy link
Collaborator

domenic commented Dec 17, 2015

They differ in the case of invoking a non-scripted cross-realm same-origin function. The current realm is that of the function, whereas the incumbent script represents that of the caller.

Apologies if I am confused, but from my understanding the caller script is the entry script, and the incumbent script is that of the function. A code example might help clarify.

@bholley
Copy link
Collaborator Author

bholley commented Dec 17, 2015

No, the entry script is the script that was first entered by the platform (i.e. via event listener dispatch), before any cross-global function calls happen. It's a dumb concept but needed for web-compat.

This is all described in https://www.w3.org/Bugs/Public/show_bug.cgi?id=26603#c0 . Entry global, incumbent global, and current realm global can all differ from each other.

@domenic
Copy link
Collaborator

domenic commented Dec 17, 2015

I guess this has all been hashed out in the previous bug so you don't need to reeducate me here. I do find that bug confusing since it contains few code examples, instead substituting a lot of unfamiliar vocabulary like "scripted function".

Anyway, I am skeptical of introducing a third concept at this stage, and would prefer we stick with entry + incumbent, and in the future redefine incumbent to mean current realm or similar. But we can wait until review time for me to voice those concerns.

@bholley
Copy link
Collaborator Author

bholley commented Dec 17, 2015

instead substituting a lot of unfamiliar vocabulary like "scripted function".

A scripted function is a function that has a SourceElements associated with it (i.e. one that was defined by script). This is relevant because incumbent script is defined in terms of SourceElements, and many functions (notably DOM methods) have no such thing.

Anyway, I am skeptical of introducing a third concept at this stage

I agree that we should reduce the number of concepts. We will basically always need Current Realm and Entry Global, so it's a question of whether we can write this spec to avoid depending on Incumbent Global, which is something that would ideally be removed.

@annevk
Copy link
Owner

annevk commented Dec 18, 2015

I think if we use "this' Realm's corresponding environment settings object's effective script origin" for where I wrote "this' Realm's global object's effective script origin" above we should also be good, no?

@domenic
Copy link
Collaborator

domenic commented Dec 18, 2015

No. (1) It's not clear what "this' Realm" refers to; (2) Realms don't have corresponding environment settings objects.

@annevk
Copy link
Owner

annevk commented Dec 18, 2015

An object is always created in some Realm/global object, that's where it's prototype et al come from. You said that since you can get from a environment settings object to a Realm, you can also go the other way around. I guess the language might need some changes, but I was hoping that much would be clear.

@domenic
Copy link
Collaborator

domenic commented Dec 18, 2015

I guess this has probably been discussed before, so apologies again. But does every implementation actually store an object's realm on each object, beyond just creation time? It seems unlikely you'd want to add another 32/64 bits to each object and carry that around forever.

@bholley
Copy link
Collaborator Author

bholley commented Dec 18, 2015

Gecko/SM stores it on everything (it's actually inferred from various other things). ISTR Boris saying that Blink/V8 stored it for Functions, but not Objects. But I'm not totally sure.

@domenic
Copy link
Collaborator

domenic commented Dec 18, 2015

Yeah, per the spec only functions have realms.

@annevk
Copy link
Owner

annevk commented Jan 4, 2016

Okay, I was just trying to find a way around using the incumbent settings object since that does not really match what we want in the long run. (To find the realm, could we just enumerate the realms in the "continent" and see which one has the corresponding prototype object?)

@annevk
Copy link
Owner

annevk commented Jan 4, 2016

So above @domenic says he's skeptical of introducing a third concept (current realm), @bholley asserts we'll need that one either way, but that point is not followed up on (perhaps due to my comment about this' Realm).

@bholley
Copy link
Collaborator Author

bholley commented Jan 11, 2016

So, the issue of whether or not non-function objects can easily find their realm isn't relevant here. We aren't talking about the realm of the cross-origin objects, but rather the realm of the code that is accessing them. Code that accesses a property is either a top-level script or a function, both of which should have easily-accessible realms.

The "current realm" and "incumbent script" are usually the same, but the concept of "incumbent script" is more complicated because it has to resolve to some script somewhere, which is tricky in certain asynchronous cases (i.e. setTimeout(someNativeFunction.bind(...), 0) when there is no script on the stack when the function runs. In that case, the Incumbent Script needs to remember what script was running when the WebIDL callback was created.

So consider the case where we have same-origin windows A and B and cross-origin C. In the case where A does:

B.setTimeout(B.Object.getOwnPropertyDescriptor.bind(null, C, 'location'))

The access check algorithm will run against window B in the "current realm" strategy (since that's where the function lives) and A in the "incumbent script" strategy (since that's how incumbent script deals with asynchronous calls to non-scripted functions).

For access-control stuff, we want to do the simple thing of asking "can the function that's currently executing access this thing". Our script security architecture is currently unaware of the concept of incumbent script (since it's only used for edge cases), and I'm not sure I could easily add it.

@annevk
Copy link
Owner

annevk commented Jan 12, 2016

  1. Some specification would still need to define "current realm". Currently I don't think that's covered anywhere.
  2. This means that one part of the crossOriginKey in https://github.com/annevk/html-cross-origin-objects/blob/master/Location.md would be current realm's global object's document's effective script origin. But what would the other part be? this' associated Document's effective script origin?

@annevk
Copy link
Owner

annevk commented Jan 12, 2016

Actually, 1 is addressed by ECMAScript, which defines "the current Realm".

@annevk
Copy link
Owner

annevk commented Jan 12, 2016

(As for earlier, apparently per IDL all IDL defined objects have an associated realm/global. So that is in fact available.)

@bholley
Copy link
Collaborator Author

bholley commented Jan 13, 2016

The other part of the key is the property name.

There's also the weirdness that, at least in Gecko, we clear the map when document.domain changes on either side. It might be possible to represent this behavior by also adding the effective script origin of |this| into the tuple, since you can never revisit an earlier value of document.domain.

@annevk annevk closed this as completed in 99630e9 Jan 13, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants