Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 1:44 PM, Tyler Close  wrote:
> On Fri, May 14, 2010 at 12:27 PM, Dirk Pranke  wrote:
>> On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:
>>> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke  wrote:
 On Fri, May 14, 2010 at 10:18 AM, Tyler Close  
 wrote:
> On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
>> OK, so there's two vulnerability scenarios:
>
> Actually, there is at least one other kind of vulnerability in the
> CORS design that has not been mentioned by anyone yet and that does
> not require XSS or untrusted code.
>
> Before I describe the attack, I want to remind everyone that the
> purpose of this particular scenario was to study the usability of CORS
> and UMP in a benign situation. This example only has a page from Yahoo
> talking to servers also operated by Yahoo. There are also no
> side-effects in this example; it's purely a data presentation example.
> Given that CORS and UMP are new protocols and that this is the most
> benign scenario we can conjure, I think it's fair to expect a solution
> with strong security properties. It should be damning if the solution
> to this very simple scenario introduces complex security problems.
>

 We are talking about enabling a class of functionality (cross-origin
 messaging) that isn't currently possible on the web. Obviously if it is
 possible to do so securely and easily, that's a good thing. If that is not
 possible, and the options are to enable things that have relative degrees
 of security or ease of use, then it becomes much more debatable.
 "Damning" is a strong word to use in this situation,
>>>
>>> If the introduced security problems are complex and therefore hard or
>>> infeasible to solve, then "damning" is the right word. If the simple,
>>> benign scenario is made infeasible, that's damning.
>>>
  especially since I
 think most people would see the interchange between Maciej and I that
 neither solution (CORS or UMP) makes things trivially securable. Another
 conclusion could be that doing this stuff is just hard.
>>>
>>> There's a big difference between "trivially" and infeasible. What are
>>> the issues with UMP where we cannot provide concrete guidance to
>>> developers? As I've shown, there are hard unknowns in the CORS
>>> solution.
>>
>> You've shown that there are cases where CORS is not secure. I don't know that
>> I would agree with your assessment that you've shown that there are
>> "hard unknowns".
>
> Further down in this email, you punt on my example, saying that it
> can't be deployed. If there are classes of applications that CORS
> cannot address, and these classes are important, then there are "hard
> unknowns" in CORS.

I should have mentioned that, as many others have pointed out, simply running
the widget off-origin (or in a sandboxed iframe) would also work. I do not agree
with your second sentence. We know the circumstances that make cookie-based
solutions dangers; you yourself have been very helpful in pointing them out.

So, I don't think your "hard unknown" characterization is accurate.

> For example, will the Security Considerations
> section of CORS have to say:
>
> "It is not safe in CORS to make a GET request for public data using a
> URL obtained from a possibly malicious party. Validating the URL
> requires global knowledge of all origins that might grant special
> access to the requestor's origin, and so return private user data."

Yes, one would imagine saying something quite similar to that.

>> As Maciej has shown, simply saying "make sure the URL can't be easily
>> obtained" is not
>> that easy.
>
> I saw him assert that. I didn't see him show that. What are the
> pitfalls that have not been addressed in the UMP spec?

Well, he didn't show that any more than I showed how to get the unguessable
URL in the first place. However, the fact that he caught errors in my
description
of what you had to protect against seemed like a strong argument.

>
> If the Yahoo Finance portfolio was designed to use UMP instead of
> CORS, this hack would not compromise any private
> portfolio data since the attacker doesn't know the unguessable secret
> for anyone's private portfolio.
>

 If the code had been audited, then it is reasonable to assume that someone
 would have caught that allowing the HotTrades service to tell the user to
 fetch *any url at all* was a bad idea, and the API should have been
 restricted to "GET http://finance.yahoo.com/stock/%s/instaprice"; instead
 of "GET %s".
>>>
>>> You've changed the scenario so that now HotTrades can only happen on
>>> Yahoo listed securities, instead of those listed on any exchange in
>>> the world. You have to allow fetching of any URL to make the
>>> application work.
>>
>> If that is true, then a reasonable audit would not allow that app to run on
>> my.yahoo.com, because 

Re: widget example of CORS and UMP

2010-05-14 Thread Tyler Close
On Fri, May 14, 2010 at 12:27 PM, Dirk Pranke  wrote:
> On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:
>> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke  wrote:
>>> On Fri, May 14, 2010 at 10:18 AM, Tyler Close  wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
> OK, so there's two vulnerability scenarios:

 Actually, there is at least one other kind of vulnerability in the
 CORS design that has not been mentioned by anyone yet and that does
 not require XSS or untrusted code.

 Before I describe the attack, I want to remind everyone that the
 purpose of this particular scenario was to study the usability of CORS
 and UMP in a benign situation. This example only has a page from Yahoo
 talking to servers also operated by Yahoo. There are also no
 side-effects in this example; it's purely a data presentation example.
 Given that CORS and UMP are new protocols and that this is the most
 benign scenario we can conjure, I think it's fair to expect a solution
 with strong security properties. It should be damning if the solution
 to this very simple scenario introduces complex security problems.

>>>
>>> We are talking about enabling a class of functionality (cross-origin
>>> messaging) that isn't currently possible on the web. Obviously if it is
>>> possible to do so securely and easily, that's a good thing. If that is not
>>> possible, and the options are to enable things that have relative degrees
>>> of security or ease of use, then it becomes much more debatable.
>>> "Damning" is a strong word to use in this situation,
>>
>> If the introduced security problems are complex and therefore hard or
>> infeasible to solve, then "damning" is the right word. If the simple,
>> benign scenario is made infeasible, that's damning.
>>
>>>  especially since I
>>> think most people would see the interchange between Maciej and I that
>>> neither solution (CORS or UMP) makes things trivially securable. Another
>>> conclusion could be that doing this stuff is just hard.
>>
>> There's a big difference between "trivially" and infeasible. What are
>> the issues with UMP where we cannot provide concrete guidance to
>> developers? As I've shown, there are hard unknowns in the CORS
>> solution.
>
> You've shown that there are cases where CORS is not secure. I don't know that
> I would agree with your assessment that you've shown that there are
> "hard unknowns".

Further down in this email, you punt on my example, saying that it
can't be deployed. If there are classes of applications that CORS
cannot address, and these classes are important, then there are "hard
unknowns" in CORS. For example, will the Security Considerations
section of CORS have to say:

"It is not safe in CORS to make a GET request for public data using a
URL obtained from a possibly malicious party. Validating the URL
requires global knowledge of all origins that might grant special
access to the requestor's origin, and so return private user data."

> As Maciej has shown, simply saying "make sure the URL can't be easily
> obtained" is not
> that easy.

I saw him assert that. I didn't see him show that. What are the
pitfalls that have not been addressed in the UMP spec?

 If the Yahoo Finance portfolio was designed to use UMP instead of
 CORS, this hack would not compromise any private
 portfolio data since the attacker doesn't know the unguessable secret
 for anyone's private portfolio.

>>>
>>> If the code had been audited, then it is reasonable to assume that someone
>>> would have caught that allowing the HotTrades service to tell the user to
>>> fetch *any url at all* was a bad idea, and the API should have been
>>> restricted to "GET http://finance.yahoo.com/stock/%s/instaprice"; instead
>>> of "GET %s".
>>
>> You've changed the scenario so that now HotTrades can only happen on
>> Yahoo listed securities, instead of those listed on any exchange in
>> the world. You have to allow fetching of any URL to make the
>> application work.
>
> If that is true, then a reasonable audit would not allow that app to run on
> my.yahoo.com, because of the dangers involved.

Or, a reasonable audit could say: "that's a fine app, so long as
you're using UMP". If CORS requires the app to be rejected, that's a
failure for CORS and this WG.

I see the WG's role here as defining a protocol that enables
applications. Saying "don't do that", as has become popular of late on
this list, is failure.

>> A possible CORS solution is to check that the URL
>> does not refer back to a user private resource on my.yahoo.com and so
>> do a check on the domain in the URL from HotTrades. However, now you
>> have to wonder about other domains that accept cross-domain requests
>> from my.yahoo.com, such as finance.yahoo.com. How do you list all
>> other domains that might be giving special cross-domain access to
>> my.yahoo.com? You can't; it's an unbounded list that is not even under

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 12:27 PM, Tyler Close  wrote:
> On Fri, May 14, 2010 at 12:20 PM, Ojan Vafai  wrote:
>> On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:
>>>
>>> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke 
>>> wrote:
>>> > You are correct that it is possible to use CORS unsafely. It is possible
>>> > to use
>>> > UMP unsafely,
>>>
>>> Again, that is broken logic. It is possible to write unsafe code in
>>> C++, but it is also possible to write unsafe code in Java, so there's
>>> no security difference between the two languages. Please, this
>>> illogical argument needs to die.
>>
>> This feels like a legal proceeding. Taken out of context, this sounds
>> illogical, in the context of the rest of the paragraph Dirk's point makes
>> perfect sense.
>
> My email included all of Dirk's text. I didn't remove it from context.
> I don't think it makes any sense, even in context.
>
>> In the same way that CORS has security problems, so does UMP.
>
> No, not in "the same way". The security issues are different in nature
> and severity. You can't just say there exist problems in both, so
> they're equivalent. That's not sensible.

Ojan said "in the same way", not me, and I did not say that they were
equivalent. I agree that the security issues are different in nature.
Your assessment of the relative severity of the two problems differs
from others' assessments.

At this point, I think this thread has run its course, unless there
are further specific criticisms against the example I gave.

I think the important takeaway is that as long as the two sites are
only running trusted code (i.e., no third party gadgets), CORS met the
intended use case securely. As soon as a third party was introduced,
the potential for confused deputies arose and life got a whole lot
more complicated.

-- Dirk



Re: widget example of CORS and UMP

2010-05-14 Thread Tyler Close
On Fri, May 14, 2010 at 12:20 PM, Ojan Vafai  wrote:
> On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:
>>
>> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke 
>> wrote:
>> > You are correct that it is possible to use CORS unsafely. It is possible
>> > to use
>> > UMP unsafely,
>>
>> Again, that is broken logic. It is possible to write unsafe code in
>> C++, but it is also possible to write unsafe code in Java, so there's
>> no security difference between the two languages. Please, this
>> illogical argument needs to die.
>
> This feels like a legal proceeding. Taken out of context, this sounds
> illogical, in the context of the rest of the paragraph Dirk's point makes
> perfect sense.

My email included all of Dirk's text. I didn't remove it from context.
I don't think it makes any sense, even in context.

> In the same way that CORS has security problems, so does UMP.

No, not in "the same way". The security issues are different in nature
and severity. You can't just say there exist problems in both, so
they're equivalent. That's not sensible.

> For example, I don't understand how UMP can ever work with GET requests.
> Specifically, how do you deal with users sharing URLs with malicious
> parties? Or is that not considered a problem?

You don't expose dangerous shared secrets to the user. You hide them
away where the user won't accidentally get at them. That's what
cookies try to do, but rather badly, as Adam has shown. There are
other ways to hide secret tokens from the user.

--Tyler

-- 
"Waterken News: Capability security on the Web"
http://waterken.sourceforge.net/recent.html



Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:
> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke  wrote:
>> On Fri, May 14, 2010 at 10:18 AM, Tyler Close  wrote:
>>> On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
 OK, so there's two vulnerability scenarios:
>>>
>>> Actually, there is at least one other kind of vulnerability in the
>>> CORS design that has not been mentioned by anyone yet and that does
>>> not require XSS or untrusted code.
>>>
>>> Before I describe the attack, I want to remind everyone that the
>>> purpose of this particular scenario was to study the usability of CORS
>>> and UMP in a benign situation. This example only has a page from Yahoo
>>> talking to servers also operated by Yahoo. There are also no
>>> side-effects in this example; it's purely a data presentation example.
>>> Given that CORS and UMP are new protocols and that this is the most
>>> benign scenario we can conjure, I think it's fair to expect a solution
>>> with strong security properties. It should be damning if the solution
>>> to this very simple scenario introduces complex security problems.
>>>
>>
>> We are talking about enabling a class of functionality (cross-origin
>> messaging) that isn't currently possible on the web. Obviously if it is
>> possible to do so securely and easily, that's a good thing. If that is not
>> possible, and the options are to enable things that have relative degrees
>> of security or ease of use, then it becomes much more debatable.
>> "Damning" is a strong word to use in this situation,
>
> If the introduced security problems are complex and therefore hard or
> infeasible to solve, then "damning" is the right word. If the simple,
> benign scenario is made infeasible, that's damning.
>
>>  especially since I
>> think most people would see the interchange between Maciej and I that
>> neither solution (CORS or UMP) makes things trivially securable. Another
>> conclusion could be that doing this stuff is just hard.
>
> There's a big difference between "trivially" and infeasible. What are
> the issues with UMP where we cannot provide concrete guidance to
> developers? As I've shown, there are hard unknowns in the CORS
> solution.

You've shown that there are cases where CORS is not secure. I don't know that
I would agree with your assessment that you've shown that there are
"hard unknowns".

As Maciej has shown, simply saying "make sure the URL can't be easily
obtained" is not
that easy.

>>> If the Yahoo Finance portfolio was designed to use UMP instead of
>>> CORS, this hack would not compromise any private
>>> portfolio data since the attacker doesn't know the unguessable secret
>>> for anyone's private portfolio.
>>>
>>
>> If the code had been audited, then it is reasonable to assume that someone
>> would have caught that allowing the HotTrades service to tell the user to
>> fetch *any url at all* was a bad idea, and the API should have been
>> restricted to "GET http://finance.yahoo.com/stock/%s/instaprice"; instead
>> of "GET %s".
>
> You've changed the scenario so that now HotTrades can only happen on
> Yahoo listed securities, instead of those listed on any exchange in
> the world. You have to allow fetching of any URL to make the
> application work.

If that is true, then a reasonable audit would not allow that app to run on
my.yahoo.com, because of the dangers involved.

> A possible CORS solution is to check that the URL
> does not refer back to a user private resource on my.yahoo.com and so
> do a check on the domain in the URL from HotTrades. However, now you
> have to wonder about other domains that accept cross-domain requests
> from my.yahoo.com, such as finance.yahoo.com. How do you list all
> other domains that might be giving special cross-domain access to
> my.yahoo.com? You can't; it's an unbounded list that is not even under
> the control of my.yahoo.com.
>
>> This is also what Maciej said in his Don't Be a Deputy
>> Slides - "Guarantee that requests on behalf of a third party look different 
>> than
>> your own".
>
> How do I make a GET request for public data look different? I look
> forward to seeing DBAD explained in greater depth. I am completely
> unconvinced by what has been presented to date.

If it is not possible to deploy an app with the level of distinction
possible, then
you don't deploy it.

>
>> You are correct that it is possible to use CORS unsafely. It is possible to 
>> use
>> UMP unsafely,
>
> Again, that is broken logic. It is possible to write unsafe code in
> C++, but it is also possible to write unsafe code in Java, so there's
> no security difference between the two languages. Please, this
> illogical argument needs to die.
>

I did not say that they were the same.

>> since - as others have expressed - everything depends on the URL
>> being unguessable.
>
> or putting an unguessable token somewhere else in the request.
>
> In CORS, everything depends on the cookie being unguessable and
> confidential. Adam has shown how har

Re: widget example of CORS and UMP

2010-05-14 Thread Ojan Vafai
On Fri, May 14, 2010 at 12:00 PM, Tyler Close  wrote:

> On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke 
> wrote:
> > You are correct that it is possible to use CORS unsafely. It is possible
> to use
> > UMP unsafely,
>
> Again, that is broken logic. It is possible to write unsafe code in
> C++, but it is also possible to write unsafe code in Java, so there's
> no security difference between the two languages. Please, this
> illogical argument needs to die.


This feels like a legal proceeding. Taken out of context, this sounds
illogical, in the context of the rest of the paragraph Dirk's point makes
perfect sense. In the same way that CORS has security problems, so does UMP.

For example, I don't understand how UMP can ever work with GET requests.
Specifically, how do you deal with users sharing URLs with malicious
parties? Or is that not considered a problem?

Ojan


Re: widget example of CORS and UMP

2010-05-14 Thread Tyler Close
On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke  wrote:
> On Fri, May 14, 2010 at 10:18 AM, Tyler Close  wrote:
>> On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
>>> OK, so there's two vulnerability scenarios:
>>
>> Actually, there is at least one other kind of vulnerability in the
>> CORS design that has not been mentioned by anyone yet and that does
>> not require XSS or untrusted code.
>>
>> Before I describe the attack, I want to remind everyone that the
>> purpose of this particular scenario was to study the usability of CORS
>> and UMP in a benign situation. This example only has a page from Yahoo
>> talking to servers also operated by Yahoo. There are also no
>> side-effects in this example; it's purely a data presentation example.
>> Given that CORS and UMP are new protocols and that this is the most
>> benign scenario we can conjure, I think it's fair to expect a solution
>> with strong security properties. It should be damning if the solution
>> to this very simple scenario introduces complex security problems.
>>
>
> We are talking about enabling a class of functionality (cross-origin
> messaging) that isn't currently possible on the web. Obviously if it is
> possible to do so securely and easily, that's a good thing. If that is not
> possible, and the options are to enable things that have relative degrees
> of security or ease of use, then it becomes much more debatable.
> "Damning" is a strong word to use in this situation,

If the introduced security problems are complex and therefore hard or
infeasible to solve, then "damning" is the right word. If the simple,
benign scenario is made infeasible, that's damning.

>  especially since I
> think most people would see the interchange between Maciej and I that
> neither solution (CORS or UMP) makes things trivially securable. Another
> conclusion could be that doing this stuff is just hard.

There's a big difference between "trivially" and infeasible. What are
the issues with UMP where we cannot provide concrete guidance to
developers? As I've shown, there are hard unknowns in the CORS
solution.

>> If the Yahoo Finance portfolio was designed to use UMP instead of
>> CORS, this hack would not compromise any private
>> portfolio data since the attacker doesn't know the unguessable secret
>> for anyone's private portfolio.
>>
>
> If the code had been audited, then it is reasonable to assume that someone
> would have caught that allowing the HotTrades service to tell the user to
> fetch *any url at all* was a bad idea, and the API should have been
> restricted to "GET http://finance.yahoo.com/stock/%s/instaprice"; instead
> of "GET %s".

You've changed the scenario so that now HotTrades can only happen on
Yahoo listed securities, instead of those listed on any exchange in
the world. You have to allow fetching of any URL to make the
application work. A possible CORS solution is to check that the URL
does not refer back to a user private resource on my.yahoo.com and so
do a check on the domain in the URL from HotTrades. However, now you
have to wonder about other domains that accept cross-domain requests
from my.yahoo.com, such as finance.yahoo.com. How do you list all
other domains that might be giving special cross-domain access to
my.yahoo.com? You can't; it's an unbounded list that is not even under
the control of my.yahoo.com.

> This is also what Maciej said in his Don't Be a Deputy
> Slides - "Guarantee that requests on behalf of a third party look different 
> than
> your own".

How do I make a GET request for public data look different? I look
forward to seeing DBAD explained in greater depth. I am completely
unconvinced by what has been presented to date.

> You are correct that it is possible to use CORS unsafely. It is possible to 
> use
> UMP unsafely,

Again, that is broken logic. It is possible to write unsafe code in
C++, but it is also possible to write unsafe code in Java, so there's
no security difference between the two languages. Please, this
illogical argument needs to die.

> since - as others have expressed - everything depends on the URL
> being unguessable.

or putting an unguessable token somewhere else in the request.

In CORS, everything depends on the cookie being unguessable and
confidential. Adam has shown how hard that is.

> Many people seem to feel that this is at least as
> great a flaw
> as the ambient authority flaw.

As you and Maciej discussed, a truly secure solution requires the use
of unguessable secrets outside of cookies. Whether you argue for CORS
or UMP, you must have techniques for protecting these non-cookie
secrets.

> So, to me, your argument suggests that we either should not implement
> either solution,
> which no one will find acceptable, or we should implement a solution
> that requires
> *both* unguessable tokens and cookies.

I don't follow your logic here. We have techniques for protecting
unguessable tokens outside of cookies. We know that cookies *don't*
provide a good way to protec

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 10:18 AM, Tyler Close  wrote:
> On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
>> OK, so there's two vulnerability scenarios:
>
> Actually, there is at least one other kind of vulnerability in the
> CORS design that has not been mentioned by anyone yet and that does
> not require XSS or untrusted code.
>
> Before I describe the attack, I want to remind everyone that the
> purpose of this particular scenario was to study the usability of CORS
> and UMP in a benign situation. This example only has a page from Yahoo
> talking to servers also operated by Yahoo. There are also no
> side-effects in this example; it's purely a data presentation example.
> Given that CORS and UMP are new protocols and that this is the most
> benign scenario we can conjure, I think it's fair to expect a solution
> with strong security properties. It should be damning if the solution
> to this very simple scenario introduces complex security problems.
>

We are talking about enabling a class of functionality (cross-origin
messaging) that isn't currently possible on the web. Obviously if it is
possible to do so securely and easily, that's a good thing. If that is not
possible, and the options are to enable things that have relative degrees
of security or ease of use, then it becomes much more debatable.
"Damning" is a strong word to use in this situation, especially since I
think most people would see the interchange between Maciej and I that
neither solution (CORS or UMP) makes things trivially securable. Another
conclusion could be that doing this stuff is just hard.

> First I'll explain a concrete attack against the concrete example, and
> then I'll generalize it to explain why we should expect this problem
> to be recurring.
>
> The CORS solution to the scenario creates a widely known URL,
> "http://finance.yahoo.com/api/v1/my_portfolio";, that is treated
> specially when the request happens to come from the my.yahoo.com
> origin. If you have tunnel vision on only the portfolio widget, then
> you might see no problem, but there are also other pages with other
> content on the my.yahoo.com domain. What happens if they make a
> request to this same URL, could something unexpected and wrong happen?
>
> Let's say myYahoo also has a page that fetches the "HotTrade of the
> Day" and posts its current price to my public activity
> stream, letting my friends know what investment I'm researching at the
> moment. The code for this content is audited by Yahoo and is not
> malicious.

> The "HotTrade of the day" can be on any market in the world
> and for anything. It might be hog futures in China or rice in Chicago.
> The page is used by momentum traders who just want to invest in
> anything
> that's moving quickly. Since no site lists the price of everything
> that can be traded, HotStocks returns the URL to GET the current
> price. The page content was created by a trading firm that wants to
> boost trades and attract new customers interested in trading on all of
> the world's markets.
>
> The page content makes the following requests:
>
> GET http://hottrades.foo/hotnow HTTP/1.0
> Origin: my.yahoo.com
>
> HTTP/1.0 200 OK
> Content-Type: text/plain
>
> http://finance.yahoo.com/stock/goog/instaprice
>
> and then:
>
> GET http://finance.yahoo.com/stock/goog/instaprice HTTP/1.0
> Origin: my.yahoo.com
>
> HTTP/1.0 200 OK
> Content-Type: text/plain
>
> 510.88
>
> and then:
>
> POST http://my.yahoo.com/stream/append HTTP/1.0
> Origin: my.yahoo.com
> Content-Type: text/plain
>
> I got my tip at 510.88. Find your price at:
> http://finance.yahoo.com/stock/goog/instaprice
>
> HTTP/1.0 204 OK
>
> Later, an attacker causes an unexpected URL to get into the HotTrades
> tip stream, resulting in the my.yahoo.com page doing the following:
>
> GET http://hottrades.foo/hotnow HTTP/1.0
> Origin: my.yahoo.com
>
> HTTP/1.0 200 OK
> Content-Type: text/plain
>
> http://finance.yahoo.com/api/v1/portfolio/mine
>
> and then:
>
> GET http://finance.yahoo.com/api/v1/portfolio/mine HTTP/1.0
> Origin: my.yahoo.com
>
> HTTP/1.0 200 OK
> Content-Type: application/json
>
> { /* all my portfolio data */ }
>
> and then:
>
> POST http://my.yahoo.com/stream/append HTTP/1.0
> Origin: my.yahoo.com
> Content-Type: text/plain
>
> I got my tip at { /* all my portfolio data */ }. Find your price at:
> http://finance.yahoo.com/api/v1/portfolio/mine
>
> HTTP/1.0 204 OK
>
> If the Yahoo Finance portfolio was designed to use UMP instead of
> CORS, this hack would not compromise any private
> portfolio data since the attacker doesn't know the unguessable secret
> for anyone's private portfolio.
>

If the code had been audited, then it is reasonable to assume that someone
would have caught that allowing the HotTrades service to tell the user to
fetch *any url at all* was a bad idea, and the API should have been
restricted to "GET http://finance.yahoo.com/stock/%s/instaprice"; instead
of "GET %s". This is also what Maciej said in his Don't Be a Deput

Re: widget example of CORS and UMP

2010-05-14 Thread Tyler Close
On Fri, May 14, 2010 at 11:00 AM, Dirk Pranke  wrote:
> On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
>> 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:
>> .
>>
>
> Sure.

Is someone claiming that the CORS cookie solution does not require use
of a random number generator? What's in the cookie and where did it
come from?

Access to a good random number generator is a requirement for either
solution and so is not relevant to this discussion.

--Tyler

-- 
"Waterken News: Capability security on the Web"
http://waterken.sourceforge.net/recent.html



Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 1:17 AM, Anne van Kesteren  wrote:
> On Fri, 14 May 2010 03:40:12 +0200, Dirk Pranke 
> wrote:
>>
>> Exactly, so the off-domain IFRAME is the only option here.
>
>  is an alternative solution, if you
> want everything in the same document.
>

HTML 5 to the rescue!

-- Dirk



Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
>
>> On May 13, 2010, at 6:40 PM, Dirk Pranke wrote:
>
>>> On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak  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 n

Re: widget example of CORS and UMP

2010-05-14 Thread Tyler Close
On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak  wrote:
> OK, so there's two vulnerability scenarios:

Actually, there is at least one other kind of vulnerability in the
CORS design that has not been mentioned by anyone yet and that does
not require XSS or untrusted code.

Before I describe the attack, I want to remind everyone that the
purpose of this particular scenario was to study the usability of CORS
and UMP in a benign situation. This example only has a page from Yahoo
talking to servers also operated by Yahoo. There are also no
side-effects in this example; it's purely a data presentation example.
Given that CORS and UMP are new protocols and that this is the most
benign scenario we can conjure, I think it's fair to expect a solution
with strong security properties. It should be damning if the solution
to this very simple scenario introduces complex security problems.

First I'll explain a concrete attack against the concrete example, and
then I'll generalize it to explain why we should expect this problem
to be recurring.

The CORS solution to the scenario creates a widely known URL,
"http://finance.yahoo.com/api/v1/my_portfolio";, that is treated
specially when the request happens to come from the my.yahoo.com
origin. If you have tunnel vision on only the portfolio widget, then
you might see no problem, but there are also other pages with other
content on the my.yahoo.com domain. What happens if they make a
request to this same URL, could something unexpected and wrong happen?

Let's say myYahoo also has a page that fetches the "HotTrade of the
Day" and posts its current price to my public activity
stream, letting my friends know what investment I'm researching at the
moment. The code for this content is audited by Yahoo and is not
malicious. The "HotTrade of the day" can be on any market in the world
and for anything. It might be hog futures in China or rice in Chicago.
The page is used by momentum traders who just want to invest in
anything
that's moving quickly. Since no site lists the price of everything
that can be traded, HotStocks returns the URL to GET the current
price. The page content was created by a trading firm that wants to
boost trades and attract new customers interested in trading on all of
the world's markets.

The page content makes the following requests:

GET http://hottrades.foo/hotnow HTTP/1.0
Origin: my.yahoo.com

HTTP/1.0 200 OK
Content-Type: text/plain

http://finance.yahoo.com/stock/goog/instaprice

and then:

GET http://finance.yahoo.com/stock/goog/instaprice HTTP/1.0
Origin: my.yahoo.com

HTTP/1.0 200 OK
Content-Type: text/plain

510.88

and then:

POST http://my.yahoo.com/stream/append HTTP/1.0
Origin: my.yahoo.com
Content-Type: text/plain

I got my tip at 510.88. Find your price at:
http://finance.yahoo.com/stock/goog/instaprice

HTTP/1.0 204 OK

Later, an attacker causes an unexpected URL to get into the HotTrades
tip stream, resulting in the my.yahoo.com page doing the following:

GET http://hottrades.foo/hotnow HTTP/1.0
Origin: my.yahoo.com

HTTP/1.0 200 OK
Content-Type: text/plain

http://finance.yahoo.com/api/v1/portfolio/mine

and then:

GET http://finance.yahoo.com/api/v1/portfolio/mine HTTP/1.0
Origin: my.yahoo.com

HTTP/1.0 200 OK
Content-Type: application/json

{ /* all my portfolio data */ }

and then:

POST http://my.yahoo.com/stream/append HTTP/1.0
Origin: my.yahoo.com
Content-Type: text/plain

I got my tip at { /* all my portfolio data */ }. Find your price at:
http://finance.yahoo.com/api/v1/portfolio/mine

HTTP/1.0 204 OK

If the Yahoo Finance portfolio was designed to use UMP instead of
CORS, this hack would not compromise any private
portfolio data since the attacker doesn't know the unguessable secret
for anyone's private portfolio.

The fundamental problem with the CORS design is that it attaches
ambient permission to a well-known URL, the portfolio URL, so code
that thinks it is just fetching public data might inadvertently fetch
private data and reveal it. What URLs refer to private data versus
public data is unknowable by the web content. Any content that fetches
public data and then publishes a report on it could fall victim to
this kind of attack in a CORS world. For example, earlier Nathan was
interested in building a client-side web app that fetched Semantic Web
data from a variety of sources, computed on it and produced a result.
This app could very easily fall victim to this kind of Confused Deputy
attack in a CORS world. How is the app to know which URLs it accesses
have ambient permission attached to them that results in private data
being returned? In an UMP world, the app can fetch data without
attaching any credentials, so knows that anything that comes back must
not be user private data.

Considered only in isolation, the CORS solution might seem simple and
secure[1]. When you consider the effect this code has on the rest of
the origin and all the other code running on that origin, it clearly
not secure. How is every piece of c

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Thu, May 13, 2010 at 7:53 PM, Ian Hickson  wrote:
> On Thu, 13 May 2010, Dirk Pranke wrote:
>>
>> The initial, insecure CORS solution is straightforward ... a "gadget"
>> running on My Yahoo! sends an XHR with the users' credentials to
>> "http://finance.yahoo.com/api/v1/my_portfolio"; and gets some JSON back.
>
> If I understand this right, you are saying that the user visits
> my.yahoo.com, and that page does an XHR to finance.yahoo.com, right?
>

Yes.

>
>> One interesting aspect of the CORS solution is that there is no way for
>> the CORS-based gadget to get another user's data; it is simply not
>> possible to request it, since a different set of cookies cannot be
>> included in the request.
>>
>> The CORS solution requires you to believe in the security of proper
>> cookie handling. With an HttpOnly cookie, cookies can be handled pretty
>> safely but I imagine all of us are fairly aware that cookies get exposed
>> all the time and hence this is hardly a "perfect" solution, maybe just
>> "good enough".
>>
>> One could also observe that with the naive implementation of the CORS
>> API, *any* site could trivially fetch the user's portfolio data, which
>> is presumably not desirable, and so Yahoo! Finance would also need to
>> check the Origin: header.
>
> Actually it just needs to send back a header saying that only my.yahoo.com
> is allowed to read it, and the client will take care of it.
>

True, with a trusted client (which is generally what we're assuming).
And an untrusted
client could of course forge the Origin header.

>
>> Now suppose that My Yahoo! allows the user to install third-party
>> gadgets. Suddenly neither Yahoo! Finance nor the browser can distinguish
>> a safe request from a trusted gadget from an unsafe request from an
>> untrusted gadget.
>
> If my.yahoo.com is running _untrusted_ script in the context of
> my.yahoo.com, then forget XHR -- the game is already over long before we
> get to CORS. For example, the script could do a convincing phishing
> attack trivially, get the user's credentials, and then send them to the
> attacker for use offline. UMP or CORS are irrelevant here.
>
> If you want to run untrusted script, you can use , and
> then CORS is neutralised (since the Origin is unguessable and unforgable),
> which seems to me to be what we want in that scenario.
>

True.

-- Dirk



Re: widget example of CORS and UMP

2010-05-14 Thread Maciej Stachowiak

On May 14, 2010, at 1:17 AM, Anne van Kesteren wrote:

> On Fri, 14 May 2010 03:40:12 +0200, Dirk Pranke  wrote:
>> Exactly, so the off-domain IFRAME is the only option here.
> 
>  is an alternative solution, if you 
> want everything in the same document.

That's right, the new iframe features in HTML5 will make it easier and more 
robust to do the off-domain iframe pattern. But I'm not sure srcdoc= is 
terribly useful in this case, because it's unlikely you will want the markup 
for all of the user's gadgets to be served inline in the main gadget host 
document. That doesn't seem like a good fit for the idea that the user would 
dynamically add/remove/reposition their gadgets.

Regards,
Maciej



Re: widget example of CORS and UMP

2010-05-14 Thread Anne van Kesteren
On Fri, 14 May 2010 03:40:12 +0200, Dirk Pranke   
wrote:

Exactly, so the off-domain IFRAME is the only option here.


 is an alternative solution, if  
you want everything in the same document.



--
Anne van Kesteren
http://annevankesteren.nl/



Re: widget example of CORS and UMP

2010-05-14 Thread Maciej Stachowiak

On May 13, 2010, at 6:40 PM, Dirk Pranke wrote:

> On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak  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?

> 
>> 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.

> 
>> 
>> 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.

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: 
.


>>> 
>>> 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

Re: widget example of CORS and UMP

2010-05-13 Thread Ian Hickson
On Thu, 13 May 2010, Dirk Pranke wrote:
> 
> The initial, insecure CORS solution is straightforward ... a "gadget" 
> running on My Yahoo! sends an XHR with the users' credentials to 
> "http://finance.yahoo.com/api/v1/my_portfolio"; and gets some JSON back.

If I understand this right, you are saying that the user visits 
my.yahoo.com, and that page does an XHR to finance.yahoo.com, right?


> One interesting aspect of the CORS solution is that there is no way for 
> the CORS-based gadget to get another user's data; it is simply not 
> possible to request it, since a different set of cookies cannot be 
> included in the request.
>
> The CORS solution requires you to believe in the security of proper 
> cookie handling. With an HttpOnly cookie, cookies can be handled pretty 
> safely but I imagine all of us are fairly aware that cookies get exposed 
> all the time and hence this is hardly a "perfect" solution, maybe just 
> "good enough".
> 
> One could also observe that with the naive implementation of the CORS 
> API, *any* site could trivially fetch the user's portfolio data, which 
> is presumably not desirable, and so Yahoo! Finance would also need to 
> check the Origin: header.

Actually it just needs to send back a header saying that only my.yahoo.com 
is allowed to read it, and the client will take care of it.


> Now suppose that My Yahoo! allows the user to install third-party 
> gadgets. Suddenly neither Yahoo! Finance nor the browser can distinguish 
> a safe request from a trusted gadget from an unsafe request from an 
> untrusted gadget.

If my.yahoo.com is running _untrusted_ script in the context of 
my.yahoo.com, then forget XHR -- the game is already over long before we 
get to CORS. For example, the script could do a convincing phishing 
attack trivially, get the user's credentials, and then send them to the 
attacker for use offline. UMP or CORS are irrelevant here.

If you want to run untrusted script, you can use , and 
then CORS is neutralised (since the Origin is unguessable and unforgable), 
which seems to me to be what we want in that scenario.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: widget example of CORS and UMP

2010-05-13 Thread Dirk Pranke
On Thu, May 13, 2010 at 6:40 PM, Dirk Pranke  wrote:
> On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak  wrote:
>> I think a more likely use case for CORS does not involve embedded gadgets at 
>> all. Consider the example of a social network asking for access to your 
>> GMail contacts.
>
> Fair enough. Sounds like a different email thread; I'll see what I can do :)
>

Okay, having thought about this for a few minutes, I think that this
is essentially identical to the calendar example you worked through in
your DBAD slide deck (and which is also listed as an example use case
in the CORS spec) (it's just a GET instead of a PUT). So, rehashing
that thread here doesn't make a lot of sense, but incorporating it
into the "security considerations" section does. Do you agree?

-- Dirk



Re: widget example of CORS and UMP

2010-05-13 Thread Dirk Pranke
On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak  wrote:
>
> On May 13, 2010, at 5:37 PM, Dirk Pranke wrote:
>
>>
>> One could also observe that with the naive implementation of the CORS
>> API, *any* site could trivially fetch the user's portfolio data, which
>> is presumably not desirable, and so Yahoo! Finance would also need to
>> check the Origin: header. With the UMP solution, this is not strictly
>> necessary but might be a useful "defense in depth". The disadvantage
>> of requiring the Origin header means that this is not really an "Open"
>> API - Yahoo! Finance has to whitelist the callers. Not very web
>> friendly, but this is maybe okay since this particular API was never
>> intended to be Open.
>
> Actually, with UMP you can't check the Origin header, since it will be 
> missing (or Origin: null) regardless of the origin.. But with CORS you can 
> add defense in depth by requiring an unguessable token in the request, as 
> with the UMP solution.

Good point; you're right.

>
>>
>> Now suppose that My Yahoo! allows the user to install third-party
>> gadgets. Suddenly neither Yahoo! Finance nor the browser can
>> distinguish a safe request from a trusted gadget from an unsafe
>> request from an untrusted gadget. Since the CORS solution uses
>> well-known URLs, it is now helpless against exposing this data to a
>> third party. How can we protect against that? One solution would be to
>> run the third-party gadget in an IFRAME (and from a different domain),
>> again. But this would partially defeat the goal we started with in the
>> first place. Another approach would be to attempt to inspect the
>> widget code (either by a human or by something like Caja) and only
>> allow appropriately sanitized code to execute. However, given that the
>> URL is just a string, I suspect it would be difficult to write a
>> general purpose sanitizer to protect against this, or at least to do
>> so and allow the resulting sanitized gadget to do anything very
>> interesting. Maybe a human could do it correctly - this is more or
>> less the definition of "trusted code", after all.
>
> 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.

> 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.

>
> 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.

> 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.

>> If the page does contains both
>> the third-party gadget and the Yahoo!-provided portfolio gadget, then
>> there would have to be a way to prevent the third-party gadget from
>> being able to crawl the DOM and extract the $UNGUESSABLE_URL. I don't
>> think that that's possible unless you put the third-party gadget in an
>> IFRAME, again. Or, you can again run the third-party gadget through a
>> sanitizer, but in this case we know that you can implement this
>> programmatically, since that's what Caja does.
>
> Indeed, but a gadget running same-origin doesn't even have to craw the DOM, 
> it could use XHR or other means (e.g. iframes) to get access to any resource 
> on the origin unless somehow prevented from doing so. Which Caja does.

Agreed.

>
>>
>> A third option to protect the API would be to modify the Yahoo!
>> Finance API to require an unguessable to

Re: widget example of CORS and UMP

2010-05-13 Thread Maciej Stachowiak

On May 13, 2010, at 5:37 PM, Dirk Pranke wrote:

> 
> One could also observe that with the naive implementation of the CORS
> API, *any* site could trivially fetch the user's portfolio data, which
> is presumably not desirable, and so Yahoo! Finance would also need to
> check the Origin: header. With the UMP solution, this is not strictly
> necessary but might be a useful "defense in depth". The disadvantage
> of requiring the Origin header means that this is not really an "Open"
> API - Yahoo! Finance has to whitelist the callers. Not very web
> friendly, but this is maybe okay since this particular API was never
> intended to be Open.

Actually, with UMP you can't check the Origin header, since it will be missing 
(or Origin: null) regardless of the origin.. But with CORS you can add defense 
in depth by requiring an unguessable token in the request, as with the UMP 
solution.

> 
> Now suppose that My Yahoo! allows the user to install third-party
> gadgets. Suddenly neither Yahoo! Finance nor the browser can
> distinguish a safe request from a trusted gadget from an unsafe
> request from an untrusted gadget. Since the CORS solution uses
> well-known URLs, it is now helpless against exposing this data to a
> third party. How can we protect against that? One solution would be to
> run the third-party gadget in an IFRAME (and from a different domain),
> again. But this would partially defeat the goal we started with in the
> first place. Another approach would be to attempt to inspect the
> widget code (either by a human or by something like Caja) and only
> allow appropriately sanitized code to execute. However, given that the
> URL is just a string, I suspect it would be difficult to write a
> general purpose sanitizer to protect against this, or at least to do
> so and allow the resulting sanitized gadget to do anything very
> interesting. Maybe a human could do it correctly - this is more or
> less the definition of "trusted code", after all.

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? 
Alternately, tools like Caja would block all use of XHR other than the 
anonymous kind.

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.

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. 

> If the page does contains both
> the third-party gadget and the Yahoo!-provided portfolio gadget, then
> there would have to be a way to prevent the third-party gadget from
> being able to crawl the DOM and extract the $UNGUESSABLE_URL. I don't
> think that that's possible unless you put the third-party gadget in an
> IFRAME, again. Or, you can again run the third-party gadget through a
> sanitizer, but in this case we know that you can implement this
> programmatically, since that's what Caja does.

Indeed, but a gadget running same-origin doesn't even have to craw the DOM, it 
could use XHR or other means (e.g. iframes) to get access to any resource on 
the origin unless somehow prevented from doing so. Which Caja does.

> 
> A third option to protect the API would be to modify the Yahoo!
> Finance API to require an unguessable token even in the CORS case (so
> you would use cookies + token). This is the analogy to what we do
> today for XSRF protection. Arguably this is the most secure solution
> at all, because it would require the token-generation to be
> compromised (or the URL to be leaked) *and* the cookie to be leaked.

Indeed. CORS + Secret Token provides defense in depth. You have to have a 
Confused Deputy vulnerability *and* a compromise of your shared secret, both 
within the same time window and exploitable by the same attacker, to be 
vulnerable.

> 
> Lastly, if we say that the problem is that My Yahoo! should not have
> allowed third-party widget

widget example of CORS and UMP

2010-05-13 Thread Dirk Pranke
I mentioned earlier that I would attempt to provide a concrete use
case for CORS. Here it is; I suggest that this text be used as a basis
for part of the "security considerations" section of the spec.

If my example and the analysis is incorrect, or if this is not in fact
an intended use case for CORS, please speak up :)

The CORS "Use Cases" section cites "a service such as a news or stock
ticker can be on a central server and shared with many other servers"
as an API that might make use of CORS. Of course, it mentions the HTML
5 eventsource, which I am not very comfortable with, so I will attempt
to describe a concrete example using something I am familiar with. I
don't think my example changes anything materially and can be deployed
using otherwise existing browser technology.

There are two variants of such a service - either the service provides
generic, anonymous information (i.e., current stock prices), or it
provides customized, sensitive information. In the former case, the
service does not require authorization or presumably any real
credentials, and so the CORS and UMP solutions are essential
identical. Problem solved, value added :)

In the latter case, assume the service does provide sensitive data.
Here's a real example:

Yahoo!'s "My Yahoo!" service (my.yahoo.com) allows the user to build a
customizable page including data from multiple different services. One
option is to include portfolio information from Yahoo! Finance
(finance.yahoo.com) (*). Such components are variously called
"widgets" or "gadgets", and I assume we are all familiar with this
concept. (Google's iGoogle does the same thing, as do lots of other
services).

Historically, I believe this functionality was implemented (and may
still be) using backend service-to-service communication (so all
browser requests went from client to my.yahoo.com servers). It would
also be possible to create the desired user experience by embedding an
IFRAME pointing to a URL on finance.yahoo.com that returned the same
content.

I understand one desired usage of CORS is to allow us to remove this
IFRAME or backend communication, so that the client can directly pull
and reformat the data, and so that finance.yahoo.com need only provide
a data feed. Here is how I would imagine a regular web developer
(meaning, me) would attempt to solve the problem using CORS and UMP.

The initial, insecure CORS solution is straightforward ... a "gadget"
running on My Yahoo! sends an XHR with the users' credentials to
"http://finance.yahoo.com/api/v1/my_portfolio"; and gets some JSON
back.

The insecure UMP solution is similarly obvious, you just replace the
URL with "http://finance.yahoo.com/api/v1/portfolio/$USERID"; .

Given that Yahoo! Finance uses cookies today to identify the user, the
CORS solution is trivial to implement. The UMP solution requires My
Yahoo! to develop some way of translating $UNGUESSABLE_ID into a user
id; this could presumably be almost as easy as stuffing the session id
from the cookie into the token. This is slightly more work than the
CORS solution, but not a lot more.

Now, what are the security implications of these two designs?

One interesting aspect of the CORS solution is that there is no way
for the CORS-based gadget to get another user's data; it is simply not
possible to request it, since a different set of cookies
cannot be included in the request. The CORS solution requires you to
believe in the security of proper cookie handling. With an HttpOnly
cookie, cookies can be handled pretty safely but I imagine all of us
are fairly aware that cookies get exposed all the time and hence this
is hardly a "perfect" solution, maybe just "good enough".

 With UMP, on the other hand, the gadget can request any user's data
that can be guessed. The obvious answer to this is to change $USERID
to an $UNGUESSABLE_ID, and ensure that $UNGUESSABLE_ID isn't leaked.
It is a debatable point as to whether ensuring this is easier than
ensuring the cookies aren't leaked.

One could also observe that with the naive implementation of the CORS
API, *any* site could trivially fetch the user's portfolio data, which
is presumably not desirable, and so Yahoo! Finance would also need to
check the Origin: header. With the UMP solution, this is not strictly
necessary but might be a useful "defense in depth". The disadvantage
of requiring the Origin header means that this is not really an "Open"
API - Yahoo! Finance has to whitelist the callers. Not very web
friendly, but this is maybe okay since this particular API was never
intended to be Open.

Similarly, UMP requires the caller to somehow obtain $UNGUESSABLE_ID.
Doing so is undoubtedly some more work than not needing to do so;
whether or not this would be more work than maintaining a whitelist
would depend on the implementation of both and is outside the scope of
this note.

Given all this, both designs are relatively okay as long as you trust
what is running on My Yahoo!.

Now suppose that My Yahoo! allows th