Re: [cors] unaddressed security concerns

On Nov 3, 2009, at 5:33 PM, Tyler Close wrote:

> I was just catching up on email and thought it might be useful to
> respond to this one even though it's a couple weeks old now, since in
> general the group seems to want more examples.

Thanks for the reply.

>
> On Mon, Oct 12, 2009 at 7:19 AM, Maciej Stachowiak <mjs@apple.com>  
> wrote:
>> As a side note, I should add that Tyler's scenario would be much  
>> simpler
>> overall if printer.example.net used a grant of read access to the  
>> photo it
>> wants to print on storage.example.org, instead of granting write  
>> access to a
>> new location.
>
> In this scenario, photo.example.com has the opportunity to take the
> role of attacker in a CSRF-like attack. In the legitimate case,
> photo.example.com is expected to send a URL to printer.example.net
> which identifies the photo to be printed, such as
> <http://storage.example.org/photo123>. In the attack case,
> photo.example.com could send the URL that identifies the
> printer.example.net client list, such as
> <http://storage.example.org/clients123>. Consequently,
> photo.example.com receives a print out of the printer.example.net
> client list, instead of a photo printout.

What's the attack here? Is it information disclosure or vandalism? If  
the user should not have access to the printer.exmple.com client list,  
then printer.example.com should not be able to access that resource  
with the user's cookie. So I don't think there is a risk of  
information disclosure. There is the possibility of vandalism - that  
the photo site wastes the user's money by making them print something  
other than the photo they wanted. But it could do this simply by  
providing the URL to a resource that it does have access to, but which  
contains something undesirable (goatse for example). So I think there  
isn't a real vulnerability here.

That being said, my understanding of this threat was greatly improved  
by the discussion at TPAC. I now think the best way to address multi- 
site collaboration is by applying the DBAD discipline. Here's how I  
would do it in this case:

The storage service is designed to allow collaborative access by  
multiple sites, therefore it needs to let them distinguish their own  
requests from third-party requests. One way to do so is to partition  
resources such that each is owned by exactly one storage domain. The  
only way to share information cross-domain is to copy. Resource names  
include the domain that owns them. Then it offers the following  
command set (angle brackets are used to delimit metasyntactic  
variables):

(This may be more complicated than needed, for the sake of clarity):

Read <from>
    If the <from> resource is owned by the domain specified by Origin,  
return the data.

Write <to>\n
<filedata>
    If the <from> resource is owned by the domain specified by Origin,  
store <filedata> at the resource.

SameDomainCopy <from> <to>
    <from> and <to> must be in the same domain and must match Origin.

GetReadToken <resource>
    If the Origin header matches <resource>, return a one-time read  
token which can be used to copy a resource cross-domain

GetWriteToken <resource>
    If the Origin header matches <resource>, return a one-time read  
token which can be used to copy a resource cross-domain

CrossDomainCopy <from-domain> <from-resource> <read-token> <to-domain>  
<to-resource> <write-token>
     <read-token> must be a valid read token for <from-resource>, and  
<from-resource> must be owned by <from-domain>. <write-token> must be  
a valid write token for <to-resource>, and <to-resource> must be owned  
by <to-domain>. Origin must match at least one of <from-domain> or <to- 
domain>.

This allows two sites to agree to copy a resource from one to the  
other on storage.exmple.org without introducing a confused deputy  
hazard.

In the original scenario, photo.example.com would get a resource name  
and a write token from printer.example.net, would obtain its own read  
token for the resource to copy using GetReadToken, and then issue a  
copy request with both domains and both tokens using CrossDomainCopy.  
It's impossible for printer.example,net to make photo.example.com  
accidentally overwrite its own resources in this case, because the  
request on behalf of a third party is distinct from any request it  
would make on its own behalf. You could argue that neither Origin nor  
Cookie in the cross-domain network resources are necessary to make  
this work, but I think in this case they can make the system easier to  
build and more robust.

>
>> Or it can just ask photo.example.com to read the photo from
>> storage.example.org and send the actual data. Either of these much  
>> less
>> abusable than writing, and would be a safer approach, whether or  
>> not the
>> overall design depends on secret tokens. The grant of read access  
>> can be
>> one-time or time-limited if necessary. Thus, I think the scenario is
>> somewhat contrived. Likely cross-site interactions would not  
>> involve such a
>> complex process to transfer data. The root of the vulnerability in  
>> Tyler's
>> scenario is writing in a shared namespace to transfer data, instead  
>> of
>> simply granting read access to the existing copy, or transferring  
>> the actual
>> data bits.
>
> The semantics of the request, read versus write, are not relevant to
> the attack. As Maciej explained in the TPAC meeting today, the actual
> problem occurs when a request is composed using data received from 2
> or more sites. As an historical note, it's interesting to observe the
> initial misstep here and so conjecture that web developers may also
> misunderstand the dangers and so use CORS-with-Origin in an insecure
> way.
>
> A request composed from data received from 2 or more sites should be a
> common pattern in any *cross-origin* application. It's the nature of
> the problem space. There's no need for examples to be complicated to
> demonstrate the problem. If people find Maciej's example simpler, it
> demonstrates the vulnerability just as well.

I don't really agree that composing a request from data received from  
2 or more sites is likely to be common. Sites are doing cross-domain  
collaboration now, using techniques like OAuth, JSONP, or asking the  
user for their password for another site. To my knowledge, the sites  
doing this are general having a pure bilateral interaction that is  
well modeled by the example in my CORS background slide.

Regards,
Maciej

Received on Thursday, 5 November 2009 05:37:25 UTC