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

Re: Breaking the `opener` relationship.

From: Devdatta Akhawe <dev.akhawe@gmail.com>
Date: Mon, 1 May 2017 20:40:46 -0700
Message-ID: <CAPfop_2an+smMRkk+t3Nboq-ApK2naBwNRGJ0W7vRTuvbxamdQ@mail.gmail.com>
To: Artur Janc <aaj@google.com>
Cc: Mike West <mkwst@google.com>, 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>
Hi

First, I agree with Artur, re his concern on iframes being treated same as
new windows. I figured if its easier conceptually or for UA implementation,
I am ok with it. Especially, if we allow x-origin postMessage.

Re the postMessage threats flagged: I haven't dug deep into the Slack bug
(asking Frans on the side) but I suspect that the reason for using
postMessage was to allow cross-origin communications. If my hypothesis is
right, blocking all postMessage means that they can't adopt this proposal.

The class of issues flagged by Frans has been discussed for a long time. I
think a distinction between the opener bugs and postMessage bugs is that
with postMessage you need to opt-in: you need to add an event listener. And
there is a way to secure it: check the origin of the event. There is no
such 'localized' option for opener bugs.

You are absolutely right that this is an area where people make mistakes,
but the current proposal won't solve this bug for people who actually need
to use postMessage cross-origin. Worse, it will mean that people who need
to make cross-origin postMessages can't adopt this proposal. For example,
if a page opens two popups: one untrusted and one trusted it wants to
communicate with, it won't be able to adopt this proposal.

I am all for a separate CSP directive to control postMessage send/receive;
I think that will be very useful for a large class of web applications.

(I am biased: when our team worked on such postMessage issues back in 2010
<http://devd.me/papers/w2sp10-primitives.pdf>, even then we argued for post
message controls in CSP.)

--dev



On 28 April 2017 at 11:44, Artur Janc <aaj@google.com> wrote:

> 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
> default).
>
> 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 Tuesday, 2 May 2017 03:41:41 UTC

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