#1215 new enhancement

add CORS support

Reported by: warner Owned by:
Priority: major Milestone: undecided
Component: code-frontend-web Version: 1.8.0
Keywords: security http same-origin cors websec Cc: zooko, vikarti@…
Launchpad Bug:

Description (last modified by zooko)

If the webapi client emitted a header like this on every page:

Access-Control-Allow-Origin: *

Then, in sufficiently-modern browsers, web pages pulled from arbitrary third-party sites would be able to perform XHR to the Tahoe webapi server without interference by the regrettable "same-origin policy".

Clients who want to use this (i.e. web pages from third parties) must do a slightly different form of XHR than usual: I'm looking at this and this for details.

One quirk to keep in mind is that clients (i.e. those third parties) can set a flag on their XHR calls to cause the browser to include any cookies that the tahoe webapi might have set. We all know to not use cookies for authorization, but once we enable CORS, we should make extra sure to not add any code which accepts authority information from cookies.

Change History (14)

comment:1 Changed at 2010-12-17T23:29:10Z by warner

Tyler Close points to http://www.w3.org/TR/UMP/ as an additional spec-in-progress for this header.

comment:2 in reply to: ↑ description ; follow-ups: Changed at 2011-01-06T08:05:20Z by davidsarah

  • Keywords security http added

Replying to warner:

If the webapi client emitted a header like this on every page:

Access-Control-Allow-Origin: *

Then, in sufficiently-modern browsers, web pages pulled from arbitrary third-party sites would be able to perform XHR to the Tahoe webapi server without interference by the regrettable "same-origin policy".

This is not safe. It would be safe if the web-API server provided no ambient authority, and was not subject to any DoS attacks. Unfortunately, neither of those conditions are true, since it provides ambient upload authority to a grid. The users of a web-API server may be relying on it only listening on particular IP interfaces or only being accessible from behind a firewall to mitigate this problem. (Note that being able to connect to an interface or being behind a firewall are also ambient authorities.)

I suggest that we fix #587 and then revisit this issue.

comment:3 in reply to: ↑ 2 Changed at 2011-01-06T08:19:49Z by davidsarah

Replying to davidsarah:

I suggest that we fix #587 and then revisit this issue.

and #860.

comment:4 Changed at 2011-11-16T17:27:28Z by warner

http://www.w3.org/community/unhosted/wiki/RemoteStorage makes this even more important to implement (it mentions Tahoe as a backend, and cites CORS as the enabler).

I'm not so worried about ambient storage authority: we expose that already (form POST to /uri?t=upload), and we know it needs to be resolved, probably by passing a storage-cap along with the write-cap, which probably means a JS frontend and a bunch of UI rethinking to figure out how to share write-authority and storage-authority separately (or maybe together).

And I guess I'm not fond of arguments like "somebody might be depending upon this, so we can't change it", which are impossible to argue against (maybe our userbase is still small enough that we can actually ask all of them whether they're depending upon this particular thing, or we could raise the issue on the mailing list and give folks a month to speak up, and then change it). It's the sort of argument which created the flawed same-origin policy in the first place, such that CORS had to be developed to undo the damage.

Also, #587 is a serious science and engineering effort: we have to define Accounting, make it work, define a whole bunch of new webapi authorities, make *them* work, change the webui to use them, change the CLI commands to use them, then finally we can remove the ambient upload interface. Good stuff to have, but it's not going to happen within the next six months, probably longer.

In contrast, adding CORS support is easy and quick, and would immediately enable a large class of applications. It'd also reinforce our message of not relying on same-origin restrictions: we know the sort of obj-cap world we want to live in, where power is exercised by holding sharable references instead of by coming from magical domains.

comment:5 in reply to: ↑ 2 Changed at 2011-11-16T19:13:42Z by zooko

Replying to davidsarah:

This is not safe. It would be safe if the web-API server provided no ambient authority, and was not subject to any DoS attacks. Unfortunately, neither of those conditions are true, since it provides ambient upload authority to a grid. The users of a web-API server may be relying on it only listening on particular IP interfaces or only being accessible from behind a firewall to mitigate this problem.

I'm pretty sure that users do rely on this -- preventing other people from opening TCP connections to their gateway in order to prevent those people from using their storage space. If people could connect to your gateway, they could upload their own files from their computer into your tahoe-lafs storage space, and later retrieve the files again the same way (through your gateway). I could imagine unscrupulous people wanting to do that for file-sharing/hosting purposes (probably of the temporary kind -- until discovered and shut down).

However, what vulnerability would turning on Access-Control-Allow-Origin: * open up? If I understand correctly, it is that someone could put up a web page, and somehow get you to visit it with the web browser that is also able to connect to your gateway. Then they could put a script on that web page that uses your storage space. This doesn't seem like as likely of a problem, because in order to upload their own files they would first have to arrange for those files to be transmitted into the Javascript memory running in your web browser or onto your local filesystem. Likewise, they couldn't directly download and view the files out of your storage space later, except by somehow proxying the data back down to your web browser and then back up to their server. That sounds like an R&D project to even get it to work, and it would be useless for the "file-sharing/hosting" use case mentioned above. If you can't usefully upload and download your own files, then what's left is just a denial-of-service -- uploading random files from the user's filesystem or all-zeroes files constructed in the memory of the Javascript program itself.

This is not to say that David-Sarah's analysis is wrong. It is certainly right: the ambient authority is accessible to 3rd party scripts running in your web browser, if we allow those scripts to use Tahoe-LAFS. I'm very enthusiastic about fixing #587 and closing this vulnerability. But since the practical consequences of it, for now, seem limited, I tend to think it might be worth enabling 3rd party scripts to use Tahoe-LAFS now and see if any wonders grow there. :-)

comment:6 follow-up: Changed at 2011-11-16T23:25:48Z by davidsarah

I strongly disagree with comment:4 and comment:5. We advocate setting the web port to listen only for connections from localhost, precisely in order to mitigate the ambient authority problems with the current WUI. It's the documented way to avoidmitigate such problems, and we shouldn't make it break, introducing new and unnecessary security vulnerabilities, until we have fixed them.

However, what vulnerability would turning on Access-Control-Allow-Origin: * open up?

An XHR request is indistinguishable to the gateway from any other request, so the consequence is that an attacker who can run any script in the user's browser -- not only scripts loaded from the gateway's origin -- can do anything that the user can do with that gateway. (Because the gateway does not support "preflight" checks, this is limited to GETs and to POSTs of MIME types application/x-www-form-urlencoded, multipart/form-data, and text/plain, but that's not much of a restriction in our case.)

Last edited at 2011-11-16T23:28:01Z by davidsarah (previous) (diff)

comment:7 in reply to: ↑ 6 ; follow-up: Changed at 2011-11-17T06:21:55Z by zooko

Replying to davidsarah:

However, what vulnerability would turning on Access-Control-Allow-Origin: * open up?

An XHR request is indistinguishable to the gateway from any other request, so the consequence is that an attacker who can run any script in the user's browser -- not only scripts loaded from the gateway's origin -- can do anything that the user can do with that gateway. (Because the gateway does not support "preflight" checks, this is limited to GETs and to POSTs of MIME types application/x-www-form-urlencoded, multipart/form-data, and text/plain, but that's not much of a restriction in our case.)

Okay, thanks for the explanation. Am I right, in comment:5, that giving an attacker this power would not enable the attacker to perform the "steal your storage for my temporary file-sharing" use case?

comment:8 Changed at 2011-11-17T06:22:14Z by zooko

  • Cc zooko added

comment:9 Changed at 2011-12-29T19:56:57Z by warner

incidentally, http://caniuse.com/cors indicates that CORS is currently supported (either via XHR or IE's alternative XDR) by about 86% of web browsers.

comment:10 Changed at 2012-02-12T05:17:47Z by vikarti

  • Cc vikarti@… added

comment:11 in reply to: ↑ 7 ; follow-up: Changed at 2012-11-15T01:16:33Z by nejucomo

Replying to zooko:

Replying to davidsarah:

However, what vulnerability would turning on Access-Control-Allow-Origin: * open up?

An XHR request is indistinguishable to the gateway from any other request, so the consequence is that an attacker who can run any script in the user's browser -- not only scripts loaded from the gateway's origin -- can do anything that the user can do with that gateway. (Because the gateway does not support "preflight" checks, this is limited to GETs and to POSTs of MIME types application/x-www-form-urlencoded, multipart/form-data, and text/plain, but that's not much of a restriction in our case.)

Okay, thanks for the explanation. Am I right, in comment:5, that giving an attacker this power would not enable the attacker to perform the "steal your storage for my temporary file-sharing" use case?

I think it's quite possible for an attacker to use a victim's tahoe for their own storage:

  1. Site evil.example.com hosts two javascript payloads: The "installer", and the "daemon".
  2. victim visits evil.example.com and loads the installer, which detects a tahoe gateway.
  3. The installer uses ambient upload authority to upload the daemon into the tahoe grid.
  4. The installer directs the browser to open the daemon.
  5. The daemon performs several tasks:
    • It collects the victim's file-write capabilities (I'm not certain how feasible this is, but assume it can discover at least one capability)
    • For each write cap found, it rewrites that file to include a copy of itself.
      • The purpose of this is to increase the chance that this daemon will execute in the future without requiring the original evil.example.com vector.
      • It's easy to imagine rewriting html, but perhaps, under the assumption that the storage is backups of local file system data, it could also modify shell scripts or anything else which may be an execution vector.
    • It periodically polls an attacker controlled site waiting for download/upload commands or other commands.

I don't think the "inconvenience" of shuttling data through a victim's browser is any worthwhile barrier; it just depends on the relative costs of bandwidth, latency, storage, and lulz. The existence of millions of botnet zombies attest to their own value. ;-p

It's true that setting up this kind of system is some R&D work, but I'd bet a grey-hat who's familiar with javascript could figure out every component of the above system within several hours, except perhaps CAP discovery.

Notice that without cross domain access, an attacker with grid access can replace steps 1-4 with:

  1. The attacker uploads the daemon payload into the grid.
  2. The attacker tricks the victim into opening that daemon from tahoe in a js-enabled browser.

comment:12 in reply to: ↑ 11 Changed at 2012-11-15T02:51:54Z by nejucomo

Replying to nejucomo:

Replying to zooko:

Replying to davidsarah:

However, what vulnerability would turning on Access-Control-Allow-Origin: * open up?

An XHR request is indistinguishable to the gateway from any other request, so the consequence is that an attacker who can run any script in the user's browser -- not only scripts loaded from the gateway's origin -- can do anything that the user can do with that gateway. (Because the gateway does not support "preflight" checks, this is limited to GETs and to POSTs of MIME types application/x-www-form-urlencoded, multipart/form-data, and text/plain, but that's not much of a restriction in our case.)

Okay, thanks for the explanation. Am I right, in comment:5, that giving an attacker this power would not enable the attacker to perform the "steal your storage for my temporary file-sharing" use case?

I think it's quite possible for an attacker to use a victim's tahoe for their own storage:

  1. Site evil.example.com hosts two javascript payloads: The "installer", and the "daemon".
  2. victim visits evil.example.com and loads the installer, which detects a tahoe gateway.
  3. The installer uses ambient upload authority to upload the daemon into the tahoe grid.
  4. The installer directs the browser to open the daemon.
  5. The daemon performs several tasks:
    • It collects the victim's file-write capabilities (I'm not certain how feasible this is, but assume it can discover at least one capability)
    • For each write cap found, it rewrites that file to include a copy of itself.
      • The purpose of this is to increase the chance that this daemon will execute in the future without requiring the original evil.example.com vector.
      • It's easy to imagine rewriting html, but perhaps, under the assumption that the storage is backups of local file system data, it could also modify shell scripts or anything else which may be an execution vector.
    • It periodically polls an attacker controlled site waiting for download/upload commands or other commands.

I don't think the "inconvenience" of shuttling data through a victim's browser is any worthwhile barrier; it just depends on the relative costs of bandwidth, latency, storage, and lulz. The existence of millions of botnet zombies attest to their own value. ;-p

It's true that setting up this kind of system is some R&D work, but I'd bet a grey-hat who's familiar with javascript could figure out every component of the above system within several hours, except perhaps CAP discovery.

Notice that without cross domain access, an attacker with grid access can replace steps 1-4 with:

  1. The attacker uploads the daemon payload into the grid.
  2. The attacker tricks the victim into opening that daemon from tahoe in a js-enabled browser.

The above attack outline has several pieces and may not be entirely feasible. However, I was interested in the problem and developed an "installer" portion of the above attack posted in #1859.

comment:13 Changed at 2013-03-24T09:21:18Z by davidsarah

  • Keywords same-origin cors added

comment:14 Changed at 2013-09-14T17:40:22Z by zooko

  • Description modified (diff)
  • Keywords websec added
Note: See TracTickets for help on using tickets.