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

Reply via email to