Re: widget example of CORS and UMP

On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak <mjs@apple.com> wrote:
>
>> On May 13, 2010, at 6:40 PM, Dirk Pranke wrote:
>
>>> On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak <mjs@apple.com> wrote:
>
>> ; you're right.
>
>>> If you don't run the code in an off-domain iframe or through a sanitizer
>>> like Caja, then everything on your site is vulnerable, not just resources
>>> protected via CORS. Using different-origin iframes with postMessage to
>>> communicate to the container seems like a fine solution for third-party
>>> gadgets. What goal is it defeating? Why would embedding gadgets inline
>>> without a frame be a goal?
>
>> One could argue that maintaining off-domain iframes is a hack, or is a
>> maintenance burden. You are correct of course that if you don't do
>> either, you are vulnerable.
>
> Hack: not sure why it would be a hack. Embedding self-contained pieces of
> interactive content is *exactly* what iframes are designed for. The case
> where using iframes is a bit of ahack (in my opinion) is when you use an
> invisible iframe as a way to implement a cross-site data API, where visual
> embedding is not an issue. I think the idea of running untrusted JavaScript
> code from your own origin is terrifying, no matter how much you have tried
> to verify and restrict it. So even if I were using a Caja-style tool, I
> would still want to put the untrusted content in an off-domain iframe.
>
> Maintenance burden: I don't see that either. You could either host the
> iframe content on the domain of the gadget provider, in which case it
> reduces burden on the hosting site, or else it's easy to support an
> unbounded number of subdomain hostnames from a single server. Wheres the
> burden?
>

Speaking from the viewpoint of a (fairly naive) content developer, it
still seems like
a hassle, but you're right that it's not much of one. And, as others
have pointed out
the sandbox attribute in HTML 5 makes this pretty painless (as well as
making the
intent obvious).

At any rate, I grant that best practice would probably be to run any third-party
code in a sandboxed iframe unless you really needed to not do that.

>>> Alternately, tools like Caja would block all use of XHR other than the
>>> anonymous kind.
>>
>> Exactly, so the off-domain IFRAME is the only option here.
>
> I'm not following you. Wrapping untrusted third-party widgets with Caja
> would not prevent my.yahoo.com from doing XHR on its own behalf.
>

I guess it is I who am not following you. Why is that an issue? Even if
non-cajoled code is doing credentialled XHRs on the page, the cajoled code
can't make use of that fact.

>>>>
>>>> Thus, any of the reasonably secure ways to embed a third-party widget would
>>>> not be vulnerable.
>>>>
>>>> What about the UMP-based solution; is it vulnerable? If the page
>>>> containing the third-party gadget does not also contain the
>>>> Yahoo!-provided portfolio gadget, then the $UNGUESSABLE_ID is not
>>>> easily obtained, and so, not really.
>>>
>>> Actually, if any page served off of my.yahoo.com contains $UNGUESSABLE_ID,
>>> and the widget is embedded on the My Yahoo origin and not protected with a
>>> tool like Cja, then the third-party gadget can trivially get the unguessable
>>> ID. It doesn't even have to use it right away while the My Yahoo site is
>>> embedding widgets in an insecure way - it can exfiltrate it for later use at
>>> the time and place of its choosing.
>>
>> True. I did not consider this interestingly different, but in retrospect I
>> was perhaps wrong.
>
> It makes it more clear why tools like Caja have to restrict the networking
> that "Cajoled" content is allowed to do.
>
> This is the main risk of UMP compared to CORS. Because secret tokens are the
> only security tool you have, you have the problem of maintaining
> confidentiality of a shared secret. If that shared secret is embedded in Web
> pages you serve, and/or embedded in a URL, that is hard to do.
>
>
>> Agreed. In this particular use case, protecting that URL is probably not
>> difficult, but it is a general problem.
>
> Why do you think so? URLs tend to leak. Browsers store them all over and do
> not generally treat them like secure information. Users share them freely.
> If you want to keep something secret, the last thing you want to do is put
> it in a URL. If I were designing a secret token based defense, at minimum I
> would use POST and put the secret token in the POST body instead of in the
> URL.

While it is true that users share URLs freely, they don't tend to
share URLs that
aren't trivially exposed to them (in the URL bar, when you hover over
a link). There
are plenty of ways to create the URL that a regular user will never see. In my
experience, they are a fairly safe way of protecting confidentiality if used
properly by page authors.

Although, I do not want to downplay this concern too much.

> There are also more subtle risks to shared secrets. If you are creating your
> secrets with a bad random number generator, then they will not in fact be
> unguessable and you have a huge vulnerability. Even security experts can
> make this mistake, here is an example that impacted a huge number of people:
> <http://www.debian.org/security/2008/dsa-1571>.
>

Sure.

>>>>
>>>> Lastly, if we say that the problem is that My Yahoo! should not have
>>>> allowed third-party widgets, I will observe that the exact same
>>>> attacks can occur if the page is simply compromised some other way
>>>> (through XSS, or code embedded in an ad running on the page). The
>>>> point of this observation is that what we often believe to be trusted
>>>> code comes back to bite us.
>>>
>>> If the page is compromised through XSS, then the financial data it can
>>> access will be compromised in any case.
>>
>>
>> The data is compromised only if the data either is already on the
>> page, or if it is obtainable. In the CORS without token case, or the
>> existing server-to-server case, you lose even if the data isn't
>> already on the page, because it can be fetched without needing to know
>> anything special.
>>
>> In the UMP case (or the CORS+token case), this is only true if the
>> compromised page can also obtain the $UNGUESSABLE_ID.
>
> OK, so there's two vulnerability scenarios:
> 1) User has the Yahoo Finance gadget embedded on their My Yahoo! page. The
> My Yahoo! page has an XSS vulnerability.
> In this case, the XSS attacker can get at your financial data regardless of
> whether you use an Origin-based scheme, a secret token scheme, or both in
> combination.

Agreed.

> 2) User does not currently have the Yahoo Finance gadget embedded on their
> My Yahoo! page, but does have a Yahoo Finance account. The My Yahoo! page
> has an XSS vulnerability.
> In this case, the UMP+ secret token solution will not have a vulnerability -
> assuming the secret token only gets generated when the user takes an
> explicit action to authorize the My Yahoo! gadget with Yahoo Finance.

I'm not quite sure what you mean by this, but I'm guessing that you're
suggesting
that if the Finance gadget isn't on the page, the attacker could cause
the gadget
to be added to the page without requiring user intervention, and hence
eventually
get the secret token. Is that correct?

If so, and your set of assumptions are correct, then yeah, that would
be a problem.
I was assuming that the compromised page would not be able to easily add the
gadget to it without user interaction, but that is perhaps not a safe
assumption.

> You seem to be assuming that a CORS-based solution still has a vulnerability
> in this case, but I think that's not a valid assumption. With a CORS-based
> protocol, you would still do per-user authorization. The CORS request
> carries both an Origin header and a Cookie header, so both the requesting
> site and the user are known to the service provider. The service provider
> (Yahoo Finance in this case) should check whether the service consumer (My
> Yahoo) is authorized for that specific user. In this case, they would not
> be, since the user is not using the Yahoo Finance gadget.
> In other words, CORS does not take away your ability to do per-user
> authorization. In fact, it makes it easier since you don't need to figure
> out a tricky way to bootstrap into a secret token defense.
>
> I think by assuming per-site authorization instead of per-site+user
> authorization for CORS, you are comparing apples and oranges. It would be
> like using a per-site "API key" with UMP instead of a per-user secret token.
> That's a possible (and temptingly simple) way to use UMP, but it would not
> provide effective security.

Actually, I was assuming that you did not need per-user authorization on Yahoo!
Finance's side to add the widget to the My Yahoo! page (which is reasonable in
this case since the two services are provided in the same security domain and
the per-user authorization is provided by the same Yahoo!-wide cookie). I can
say fairly safely that this is an assumption that developers would make. You are
perhaps correct that this is a bad assumption, but I think that's the point. (*)

As to UMP using a per-site "API key", this is simply not an option, because
the cookie securely identifying (not authorizing) the user can't be sent. You
have to include (untamperable) user information in the URL.

-- Dirk

(*)  If the Finance widget was designed to be used on third-party
sites as well, things
would be different, but that was not the intent of the example.

Received on Friday, 14 May 2010 18:01:20 UTC