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 dpra...@chromium.org  
wrote:

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


iframe srcdoc=... sandbox=allow-scripts 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 14, 2010, at 1:17 AM, Anne van Kesteren wrote:

 On Fri, 14 May 2010 03:40:12 +0200, Dirk Pranke dpra...@chromium.org wrote:
 Exactly, so the off-domain IFRAME is the only option here.
 
 iframe srcdoc=... sandbox=allow-scripts 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 Dirk Pranke
On Thu, May 13, 2010 at 7:53 PM, Ian Hickson i...@hixie.ch 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 iframe sandbox, 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 Tyler Close
On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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 

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@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 m...@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 

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 ann...@opera.com wrote:
 On Fri, 14 May 2010 03:40:12 +0200, Dirk Pranke dpra...@chromium.org
 wrote:

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

 iframe srcdoc=... sandbox=allow-scripts 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 Tyler Close
On Fri, May 14, 2010 at 11:00 AM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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:
 http://www.debian.org/security/2008/dsa-1571.


 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 10:18 AM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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 Deputy
Slides - Guarantee that requests on behalf of a third party look different than
your 

Re: widget example of CORS and UMP

2010-05-14 Thread Ojan Vafai
On Fri, May 14, 2010 at 12:00 PM, Tyler Close tyler.cl...@gmail.com wrote:

 On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke dpra...@chromium.org
 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 Dirk Pranke
On Fri, May 14, 2010 at 12:00 PM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 10:18 AM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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 hard that is.

True, and yet people use it all the time to provide a good enough level of
security. 

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 12:27 PM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 12:20 PM, Ojan Vafai o...@chromium.org wrote:
 On Fri, May 14, 2010 at 12:00 PM, Tyler Close tyler.cl...@gmail.com wrote:

 On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke dpra...@chromium.org
 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:27 PM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 12:00 PM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 10:18 AM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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
 the control of my.yahoo.com.

 This is also what Maciej said in his Don't Be a Deputy
 Slides - Guarantee that requests on 

Re: widget example of CORS and UMP

2010-05-14 Thread Dirk Pranke
On Fri, May 14, 2010 at 1:44 PM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 12:27 PM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 12:00 PM, Tyler Close tyler.cl...@gmail.com wrote:
 On Fri, May 14, 2010 at 11:27 AM, Dirk Pranke dpra...@chromium.org wrote:
 On Fri, May 14, 2010 at 10:18 AM, Tyler Close tyler.cl...@gmail.com 
 wrote:
 On Fri, May 14, 2010 at 1:15 AM, Maciej Stachowiak m...@apple.com 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 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 

Re: widget example of CORS and UMP

2010-05-13 Thread Dirk Pranke
On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak m...@apple.com 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 token even in the CORS case (so
 you would use cookies + token). This is the analogy to what we do
 today for XSRF 

Re: widget example of CORS and UMP

2010-05-13 Thread Dirk Pranke
On Thu, May 13, 2010 at 6:40 PM, Dirk Pranke dpra...@chromium.org wrote:
 On Thu, May 13, 2010 at 6:13 PM, Maciej Stachowiak m...@apple.com 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 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 iframe sandbox, 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.   `._.-(,_..'--(,_..'`-.;.'