On Wed, Jan 9, 2013 at 2:24 PM, Boris Zbarsky <bzbar...@mit.edu> wrote:
> On 1/9/13 5:19 PM, Adam Barth wrote:
>> Those checks are neither required for compatibility nor security.  The
>> spec might say to perform the checks, but they aren't needed to build
>> a secure, compatible browser.
>
> OK.  So what checks do you believe are required, then?  Just effective
> script origin checks on Window?
>
> I would really appreciate it if you would actually describe the security
> model you think the spec should have instead of us having to guess what
> parts you think are needed and which parts you think are not needed, with
> more gotchas and details all the time.

Answering this question in detail would take a great deal of time.  I
can try to summarize how WebKit handles this issues.  In general
WebKit tries to follow the spec's approach to these security checks,
although there are some difference for historical reasons (e.g., not
throwing exceptions, exposing or not exposing certain properties
across origins).

Generally speaking, I'd recommend exposing as few things across
origins as possible.  For example, I view WebKit's not exposing
Document across origins as "better" than the spec's exposing it,
whereas I view WebKit's exposing window.history across origins as
"worse" than the spec's not exposing it.  IMHO, we should aim for
exposing the minimal set of things across origins.

To gather this information, I grepped the WebKit IDL files for
"CheckSecurity".  Here's what I learned:

1) By default, DOMWindow (which might translate into Window or
WindowProxy in the spec---I'd need to study that issue more carefully)
needs to perform access checks.  There are a number of properties that
are white listed, similar to what's described in the spec
(cross-origin readers get "fresh" copies of the underlying interfaces
regardless of any changes made to the DOMWindow in JavaScript and
these fresh copies have prototype chains that connect up with the
*caller's* JavaScript prototypes, not the DOMWindow's JavaScript
prototypes).

2) window.history, window.location, window.focus, window.blur,
window.close, window.closed, window.length, window.window,
window.frames, window.opener, window.parent, window.top,
window.postMessage, and window.toString are whitelisted to be exposed
across origins (often just the getters, not the setters).  There's
some additional complexity related to the names of nested browsing
context and the indexed property getter, but I believe the description
in the current spec is accurate.

3) The History interfaces works much like the DOMWindow interface
(properties are blocked by default and certain whitelisted properties
are visible across origins on the same "fresh, pristine" basis as the
properties on DOMWindow).

4) history.back, history.forward, and history.go are whitelisted.

5) The Location interface works much like DOMWindow and History, but
the only whitelisted property is the location.href setter.

6) In addition, the following APIs have extra security checks.  All
these APIs return a Node.  Before returning the Node, they check
whether the Node's document's origin is the same origin as the script
calling the API.  If not, they return null instead of the node.  (We
could potentially throw an exception here, but I'm just describing
what WebKit does, not what I think the optimum design is.)

  A) HTMLEmbedObject#getSVGDocument()
  B) HTMLFrameElement#contentDocument
  C) HTMLFrameElement#getSVGDocument()
  D) HTMLIFrameElement#contentDocument
  E) HTMLIFrameElement#getSVGDocument()
  F) HTMLObjectElement#contentDocument
  G) HTMLObjectElement#getSVGDocument()
  H) DOMWindow#frameElement

With regards to your original question about using
Function.prototype.call to manipulate the "this" value passed to
function, I don't remember the details of how we dealt with that
issue.  I'd have to write some careful test cases to study WebKit's
behavior to give you a definitive answer.  We might have either
ignored the "this" value entirely (and always operated on the object
that "held" the property originally) or we might have insisted on
always checking whether the calling script was same-origin with the
"this" parameter for the three interfaces (DOMWindow, Location, and
History) where the caller could possibly have a reference to a
cross-origin object to pass as "this".

In addition to everything described above, there are some additional
security issues related to operator eval and function eval, but I've
left them out here because they're not relevant for the HTML spec.

I should also say that it's entirely possible we've screwed up our
implementation of this security model.  If you discover that we have,
I'd prefer if you filed a security bug rather than telling the world
on this public mailing list.  :)

Adam

Reply via email to