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

Re: Breaking the `opener` relationship.

From: Artur Janc <aaj@google.com>
Date: Fri, 28 Apr 2017 20:44:04 +0200
Message-ID: <CAPYVjqq9P-UqGA4XXgtT3CjTwF4SygB29j8Py1fW=DAffoJ7BQ@mail.gmail.com>
To: Mike West <mkwst@google.com>
Cc: Alex Russell <slightlyoff@google.com>, Emily Stark <estark@google.com>, Jonathan Watt <jwatt@mozilla.com>, Anne van Kesteren <annevk@annevk.nl>, "public-webappsec@w3.org" <public-webappsec@w3.org>
On Fri, Apr 28, 2017 at 4:24 PM, Mike West <mkwst@google.com> wrote:

> On Fri, Apr 28, 2017 at 2:12 PM, Artur Janc <aaj@google.com> wrote:
>> #2 in https://wicg.github.io/isolation/#threat of Emily's doc spells out
>>> the model in broad strokes. Basically, if someone has a handle to your
>>> window, it's not really your window anymore, not fully. Locking down access
>>> to `w.postMessage()`, access to frames (`w.length`, `w.frames['name']`,
>>> `w.frames[1]`, etc), `focus()`/`blur()`, and `w.location` stand out as the
>>> things I'm concerned about. Mostly in the context of Emily's Isolation
>>> proposal, but hopefully in a generally applicable way.
>> A couple of other things: `window.stop()`
> I don't think this is exposed cross-origin today.

You're right; I meant the fact that window.stop() on the embedder affects
the state of cross-origin frames, and it would nice if it didn't, but it's
minor point and probably not worth dwelling on ;)

> getting load timings from cross-origin frames, and the ability to perform arbitrary
>> CSS/SVG transforms <https://arturjanc.com/xo-frame.html> of cross-origin
>> content, all of which enabled interesting attacks in the past. I'm not sure
>> if the latter two would be addressed by this proposal, though.
> They would not. At the moment, I'm strictly considering things that hang
> off the `WindowProxy` object. The vectors you mention here both seem like
> interesting things to defend against, but somewhat distinct from what I'm
> suggesting. Do you see them as intertwined-enough to justify tying them
> together?
> FWIW I also don't think postMessage is a huge concern here given that
>> developers already have a mechanism that lets them decide which messages
>> they trust.
> I agree with you that it should be straightforward to defend against
> `postMessage`-based attacks. As noted elsewhere, however, the `postMessage`
> API is pretty easy to get wrong, and has lead to practical attacks in the
> past. Maybe Google's doing a better job with this internally than other
> folks?

Nice try, but I don't think so ;-)

In general, I see most of the value of the proposed `opener` restrictions
in breaking access to the DOM properties you mentioned (assigning to
window.location, traversing frames, etc). I see *some* value in trying to
disable other shenanigans which leak or change state across origins like
the ones I mentioned earlier, especially if there's going to be an explicit
flag that indicates the document wants to protect itself from cross-origin
interaction; but I won't be very sad if that doesn't happen, especially
X-Frame-Options already helps protect against some of this.

I'm mostly indifferent about postMessage because I doubt that developers
who don't properly perform the one crucial security check that postMessage
requires will clamor to adopt a new feature which requires more testing
(than just checking event.origin), and which can't be easily set by their
JS framework (unlike postMessage wrappers which can do origin checks by

But just to be clear, I don't have any problem with breaking postMessage to
our document if we're being opened or iframed across origins. I just don't
want to have to -- at the same time -- block our document from talking to
iframes and widgets that we've explicitly embedded because that has little
security upside and a large compatibility downside.

> On Fri, Apr 28, 2017 at 4:15 AM, Devdatta Akhawe <dev.akhawe@gmail.com>
>>> wrote:
>>>> Even though I agree with Artur about risk priority, I am ok with
>>>> lumping iframe and window.open together for this directive.
>>> I think it would be strange to treat these distinctly: both offer
>>> third-parties access to your `WindowProxy` object. It's not clear that
>>> trusting one is any different than trusting the other, as they offer the
>>> same capabilities.
>> To clarify, I don't think we should treat window.open and iframes
>> differently, but that we should distinguish restrictions based on whether
>> (1) the document is being embedded/opened by external content, and (2) the
>> document itself decides to embed/open external content. I can see a lot of
>> benefit to (1) and would use it in many applications; I don't see much
>> benefit to (2) over existing mechanisms, and suspect it might make it less
>> deployable if we bundle these two types of restrictions.
> There's a practical challenge here, in that the `WindowProxy` checks don't
> currently have any notion of how one window got access to another.
> I'm sure we could wire it through somehow, so let's assume we could make
> the distinction. In general, `a.com` framing `b.com` does seem like an
> indication that `a.com` trusts `b.com` to some extent. I'm not sure the
> same can be said for opening `b.com` in a new window. In fact, most of
> the time I see new-window navigations, the opposite is the intent (e.g. "We
> have nothing to do with this page, we just think it might be interesting to
> you. Please come back to us when you're done? Please?").

How would an attack work in this case? It seems like an attacker would need
to persistently compromise an origin we link to, wait until the user opens
the new window, then use that window to get a handle to us and attack us by
sending a postMessage, setting location.hash or something like that
(assuming our app has a vulnerability there). There might certainly be
cases where an application wants to protect against this (and can do so
with an opener-breaking proxy page) but I'd guess that it's a couple of
orders of magnitude less frequent than the situations where we or our
widgets legitimately want to communicate with embedded cross-origin content.

> And, really, one of the wonderful things about `iframe` is that it
> separates out a chunk of content on the page. I'll bet that there are folks
> out there (maybe even on this list!) that use frames for isolation because
> they don't actually trust the content they're loading. Look at the old
> implementation of `images.google.com`, for instance, which framed the
> destination page for context.
>> But, both for window.open and iframes, I think there is value to
>>>> allowing post-messages. Post messages have a security model: the
>>>> target page can check event.origin and ignore the messages; unlike
>>>> window.opener navigation scenarios. Seconding Artur, I feel like
>>>> restricting post message will significantly affect ability to
>>>> effectively adopt this directive.
>>> Artur raised similiar concerns. *shrug* If you do the right thing with
>>> source and origin checks, then I agree with you that `postMessage()` isn't
>>> terribly dangerous. That said, we consistently see folks do the wrong thing
>>> with these checks. https://labs.detectify.com/2017/02/28/hacking-slack-
>>> using-postmessage-and-websocket-reconnect-to-steal-your-precious-token/
>>> is the most recent example I can remember of this kind of attack vector.
>>> That said, I recognize the suggestion in both your response and Artur's
>>> that blocking all cross-origin access might be overly draconian. I was
>>> trying to avoid it, but one of the suggestions that Jonathan Watt made in
>>> https://github.com/w3c/webappsec-csp/issues/194 was to turn this into a
>>> source list such that the cross-origin check would turn into a list of
>>> acceptable origins. I'm a little bit worried about the expense of injecting
>>> such an access check into our bindings, but it's an option if a flat
>>> lockdown isn't something we can work with. I'm also a little bit worried
>>> that you'll next ask for a separation between different types of
>>> cross-origin access (e.g. `postMessage` vs `location`) which I'm not
>>> excited about creating (both because of implementation complexity and
>>> developer confusion (where does named-access to frames go, for instance? Or
>>> `blur()`?). "Cross-origin stuff" seems like a narrow enough bucket on its
>>> own.
>>> WDYT?
>> I'm perfectly happy with a flat lockdown if we can apply it to case (1)
>> but not (2) ;-)
> Can you talk about the use cases you'd have for Google properties? If you
> could have unicorns and ponies, what would user agents be doing for you
> with regard to properties on window handles?

I like the idea of breaking interaction with our applications by arbitrary
third parties who embed us or open us in a new window. It seems like a
useful defense in depth against some creative attacks which are perhaps not
super frequent or damaging, but kind annoying (tabnabbing, XSS filter
infoleaks based on frame counting, and even the occasional
postMessage-based XSS!)  I believe most applications could use this and it
could be a lightweight way to get some isolation for apps which can't be in
Isolated Origins.

I do not like the idea of combining this benefit with a requirement to
break access to our document from content we iframe because then we
couldn't use it (but I see no problem if it's enabled via a separate flag).
Received on Friday, 28 April 2017 18:44:59 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:55:00 UTC