W3C home > Mailing lists > Public > public-webappsec@w3.org > April 2017

Breaking the `opener` relationship.

From: Mike West <mkwst@google.com>
Date: Thu, 27 Apr 2017 12:57:24 +0200
Message-ID: <CAKXHy=en0SbH2HtZmn2f68TsZbwPDQ1eHS8h=vgHkd+UQvsaRQ@mail.gmail.com>
To: Artur Janc <aaj@google.com>, Alex Russell <slightlyoff@google.com>, Emily Stark <estark@google.com>, Jonathan Watt <jwatt@mozilla.com>, Anne van Kesteren <annevk@annevk.nl>
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>
Forking this off and CCing some folks, as it's a sufficiently interesting
topic on its own.

On Wed, Apr 26, 2017 at 2:28 PM, Artur Janc <aaj@google.com> wrote:

>
>>>    - I'd love a solution to opener disownership that's generic.
>>>
>>> Can you clarify this? I don't understand.
>>
>
> Alex, the CSP3 draft has https://w3c.github.io/webappse
> c-csp/#directive-disown-opener which might be what you're looking for?
> FWIW I'd agree with the note in the spec and this bug
> <https://github.com/w3c/webappsec-csp/issues/194> that this needs some
> more deliberation.
>

As noted, I think that `disown-opener` is the wrong thing for a page to ask
for. Instead, I think something like
`block-cross-origin-access-via-windowproxy-and-etc`
is more accurate. That is, the goal isn't to prevent `window.opener` from
being set on the protected page. The goal instead is to prevent
cross-origin pages that gain a reference to the protected page (e.g. via
`window.open` or `<iframe>` in either direction) to use that reference to
poke the protected page in ways it might not expect.

Assuming that `https://a.com/sekrit` served a response with
`content-security-policy: block-cross-origin-access-via-windowproxy-and-etc`,
I'd expect the following behavior:

1.  `var x = window.open('https://a.com/sekrit')` executed from `
https://evil.com/` would return a `WindowProxy` object, just as it does
today. But, accessing `x.location` or `x.postMessage`, or any of the other
cross-origin attributes would throw a `SecurityError`.

2.  Likewise, `var x = window.open('https://evil.com/')` from `
https://a.com/sekrit` would give `https://evil.com/` a `window.opener`
handle to `https://a.com/sekrit`, but access would throw.

3.  `https://evil.com/` would be able to reach into `<iframe src="
https://a.com/sekrit">` via `frame.contentWindow` to get a `WindowProxy`,
but again we'd block access to the properties/methods.

4.  Likewise, if `https://a.com/sekrit` included `<iframe src="
https://evil.com/">`, the latter would gain a `window.top` handle to `
https://a.com/sekrit`, but access would throw.

It seems like this would be pretty straightforward to define in HTML (add a
flag to the settings object, set it via CSP's initialize steps, check it
somewhere around step 4 of
https://html.spec.whatwg.org/#windowproxy-getownproperty, throw), though I
think Chrome's implementation would be complicated. Firefox might have an
easier time of things given its architecture...

We could, I suppose, even tie this behavior to `window.opener = null` in
order to cut off access in an imperative way, if that turned out to be
desirable.

WDYT?

-mike
Received on Thursday, 27 April 2017 10:58:19 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 14:54:22 UTC