Re: CORS performance

On Mon, Feb 23, 2015 at 12:42 PM, Jonas Sicking <jonas@sicking.cc> wrote:

> Do we have any data on how common it is for people to use CORS with
> credentials? My impression is that it's far less common than CORS
> without credentials.
>
> If that's the case then I think we'd get most of the functionality,
> with essentially none of the risk, by only allowing server-wide
> cookie-less preflights.
>
> But data would help for sure.
>


The credentials issue is a great concern. I've seen two cases I've been
able to exploit where the Origin header is always passed back to
Access-Control-Allow-Origin with Access-Control-Allow-Credentials; not
realizing this exposes CSRF tokens and other sensitive information. Though
this is not so much data as anecdote. (One was on a company-internal
project, one briefly appeared in a software library we are using in between
stable releases.) It's not hard to find additional examples [1][2][3][4].
I've never used the credentials functionality of CORS, instead passing an
Authorization header explicitly. I think we could survive without it.

I also recently ran into the CORS performance issue. CORS seems very biased
against hypermedia services, in that it doubles the roundtrip time to an
already very "chatty" API design.

To work around these two issues, I began work on a proxy to accept
`message/http` POST requests which returns `message/http` responses
(actually for now, application/json to avoid the full RFC7230
implementation). (Existing proxies solving this problem don't have the
performance characteristics or flexibility, or both, desired around HTTP
headers, hypermedia, and streaming.) The only downside is this bypasses the
user-agent cache, but for many kinds of services the user-agent cache is
rarely utilized (for instance, jQuery's AJAX actively disables caching).

I suggest that any request I can make with this proxy (which does not
itself verify CORS before passing the request), I should be able to make
without the CORS preflight request.

The semantics of the proposed header then becomes a declaration that "This
server is accessible from the Internet" (as opposed to a request on an
intranet server made from an Internet-served page); and would then allow
the making of requests that never utilize stored user-agent data
("credentials"). (With the exception of the Date header, could this be
called deterministic, since the same XHR call will always produce the same
HTTP request?)

This definition would have the following desirable effects:

1. HTTP requests become stateless
2. Removes the possibility of exposing sensitive, stored user information
(a TRACE response, if honored, would not divulge anything the sender
doesn't already know)
3. Brings performance in line with non-browser user-agents that don't
require CORS checks
4. Eliminates the privacy and security concerns associated with CORS
work-arounds, like JSONP. As seen in [5] [6] [7]

This wouldn't introduce new security concerns, because by definition it
would not allow requests that couldn't already be made by proxy.

The `OPTIONS *` request seems appropriate for this; as it is defined to be
a request for metadata about the server itself, which is all that is
necessary.

Austin Wright.

[1]
https://github.com/primiano/blink-gitcs/blob/0b5424070e3006102e0036deea1e2e263b871eaa/LayoutTests/http/tests/security/resources/cors-redirect.php
[2]
https://github.com/wohlig/sergybackend/blob/3df9e42dccf620e53253c746022fbe1e53a97a3a/application/views/json.php
[3]
https://github.com/AslakNiclasen/ProjektOpgave/blob/7d5de466398371ab1481973bf54074ab005fffdc/Kode/ad_controller/.htaccess2.txt
[4]
https://github.com/datfinesoul/starphleet-logviewer/blob/af42371daad52fa7e7ba759e94b20024077a30bb/nginx.conf
[5] http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/
[6] https://jsonp.nodejitsu.com/
[7] https://github.com/Rob--W/cors-anywhere

Received on Friday, 6 March 2015 02:09:48 UTC