Re: [whatwg] Need to define same-origin policy for WebIDL operations/getters/setters

On 1/7/13 11:28 PM, Ian Hickson wrote:
> Per spec, even Windows actually don't have an origin. Things that have
> origins are URLs, Documents, images, audio and video elements, fonts, and
> scripts. Many of those things can have origins that are not that of the
> most obvious related (or in some cases any) Document.

Yes, I know what the spec says.

What I'm saying is that the spec is not doing anyone any favors by using 
"origin" to mean different things for different objects.

In particular, for images/audio/video the "origin" in the spec is the 
origin that's relevant for the _data_, not necessarily for the element 
itself.

> Suppose you try to get the property from a Document whose origin doesn't
> match your script's origin.
>
> Right now, this throws a SecurityError

Right.  We all agree on this part; there is no problem here.

> The check we need to add is for when you actually invoke the properties,
> in case you got the property from another Document and then apply it to
> this one.

Yes.

> The check is the same -- if the Document that is the "this" to
> which the property is being applied doesn't match the origin of the script
> that is doing the applying, throw SecurityError.

That's an option, yes.  As I said, Gecko throws TypeError like it would 
for a non-document.  That happens to require less code, and I'm not sure 
people really care about the exact exception here (though I know bholley 
disagrees with me on this).

> Right. Specifically, the new security check (for compat we still need the
> old one too, though I guess in many cases it's now redundant)

It's not redundant, because nothing says that 
subframeDoc.getElementsByTagName is actually the WebIDL-defined method; 
it could be something the script in the subframe set up.  So you have to 
block access to it no matter what.

> needs to be in getElementsByTagName()'s definition or in call()'s definition. (If the
> latter, we also need to put it in a number of other places, like the stuff
> that interacts with getters/setters.)

I would vastly prefer that this check be in the definition of the 
[[Call]], because then it can be done on the binding level, when you're 
checking the this object anyway.

> So e.g. we could put it in "call()" and define it as checking whether you
> can obtain the property on the target object before actually executing
> any code.

Is that actually needed?  There are properties you can obtain on objects 
cross-origin (like window.top) that I see no need to allow via this 
backdoor since no content depends on it now.  So I would prefer simply 
checking whether the origin of the caller matches the origin of "this".

> I don't want us to literally put the checks (in the spec) in each method /
> property of the four objects with these checks (Document, Window,
> Location, Storage), since that's a _lot_ of places to put these checks. We
> could put them in prose in the same places that have the "access" checks
> now. Or we could put them elsewhere. Where the current checks are makes
> the most sense to me, but I'm not sure exactly how to phrase them.

Or you could spec what Gecko does, which is that any WebIDL call gets 
such a check, and then it's just defined in WebIDL.  ;)

Of course that does mean defining an origin for every object (as opposed 
to data associated with the object).

> Except for having to define the origin of things for this purpose, yes,
> that's what I'm essentially saying.

OK.  So here's the thing.  Given any script-exposed object, it already 
has to be associated with a specific global.  WebIDL makes this a 
requirement, since you have to find the right prototype object for it. 
At that point, you have a Window to work with, and a Window has an 
associated Document, and that has an origin.  For object-access checks 
(again, as opposed to data-access checks), this is the right origin to use.

> I don't see why EventTarget would be subject to this (it's implemented by
> things that need checking, but presumably everything that's implemented in
> that way should just be handled by that host interface the same way as
> everything on that host interface that isn't white listed).

EventTarget isn't implemented.  It's inherited from.

> The only interfaces that are of interest here (that need them and their inherited
> and implemented interfaces checked) are Document, Window, Location, and
> Storage. At least, in the HTML spec, as far as I can tell.

   var myGetter = Object.getOwnPropertyDescriptor(Node.prototype,
                                                 "firstChild").get;
   var node = myGetter.call(crossOriginDoc);

This should throw; we agree on that, right?  So I'm not sure what we're 
disagreeing about here.  Perhaps you're thinking of this as throwing 
because of something crossOriginDoc does, while I'm thinking of it as 
throwing because of something myGetter does?  Again, right now this is 
implemented in Gecko as part of myGetter's [[Call]], so that's the way 
I'm thinking of it.

-Boris

Received on Tuesday, 8 January 2013 06:42:46 UTC