W3C home > Mailing lists > Public > public-webappsec@w3.org > June 2016

CORS restrictions on preflight (too) strict?

From: Ruben Verborgh <ruben.verborgh@ugent.be>
Date: Wed, 22 Jun 2016 13:57:38 -0700
To: public-webappsec@w3.org
Message-Id: <7F39DD85-CFC7-4036-8498-050DFA242293@ugent.be>
Dear all,

I recently had a rather troublesome experience
getting CORS to work with the Memento framework.
I've filed it as an issue [0] with the newer Fetch standard,
but wanted to document it here as well.

Memento (RFC7089) [1] provides additional HTTP headers
to perform time-based content negotiation. Concretely:
 client requests indicate their preference with Accept-Datetime
 server responses indicate the timestamp with Memento-Datetime
Negotiation can be performed in two ways [1]:
 the server redirects to the negotiated representation with 302
 the server serves the negotiated representation with 200
  (using Content-Location to indicate its URL)
For various reasons, 302-style negotiation is preferred.

In contrast to regular content type and language negotiation,
however, it is impossible to make time-based content negotiation
work in the browser cross-origin with 302-style negotiation.
This is because the CORS spec [2] requires that
requests with non-simple headers [3] (such as Accept-Datetime)
are preceded by a preflight OPTIONS request
asking the server permission to use such headers.
Moreover, in cases that need such a preflight request,
30x responses from the server are not accepted.

In other words: if the client wants to negotiate cross-origin
on content type and language, 302 is allowed.
If the client wants to negotiate cross-origin on time,
302 is not allowed and 200 is needed
(which is not appropriate in several use cases).

With regard to this problem, I have two questions:

1) Could it be a considered, in a later version of CORS,
    to mark Accept-* headers safe on requests?
    After all, no harm can be done with such headers
    (not more than with Accept or Accept-Language),
    so requiring preflight is not necessary.

2) Instead of blocking redirects after preflights altogether,
    could it be considered to either:
    a) send a second preflight request to the redirected resource?
    b) allow the preflight OPTIONS response to redirect?
    (I'd prefer a, but b saves a request.)

The practical discussion of such a use case can be found here [4],
together with a live demo [5] that uses a preflight performance hack [6].
A related discussion was held here [7].

Best regards,

Ruben Verborgh
Postdoctoral Researcher in Semantic Hypermedia
Ghent University  iMinds  Data Science Lab
http://ruben.verborgh.org/  @RubenVerborgh

[0] https://github.com/whatwg/fetch/issues/326
[1] https://tools.ietf.org/html/rfc7089
[2] https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
[3] https://www.w3.org/TR/cors/#simple-header
[4] http://ruben.verborgh.org/blog/2016/06/22/querying-history-with-linked-data/
[5] http://bit.ly/artists-york-2012
[6] https://github.com/LinkedDataFragments/Client.js/commit/a0438531bbfcbd36aec04c73ab16e8d0279f3ef1
[7] https://lists.w3.org/Archives/Public/public-webappsec/2016Jan/0119.html
Received on Wednesday, 22 June 2016 20:58:38 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:54:56 UTC