Hello.

Due to external input and internal development I recently had to work with CORS 
and the Tomcat CorsFilter and encountered the issues
https://bz.apache.org/bugzilla/show_bug.cgi?id=61101 - CorsFilter should add 
Vary header to response
https://bz.apache.org/bugzilla/show_bug.cgi?id=62343 - CORS security: 
reflecting any origin header value when configured to * is dangerous
It seems these issues have been fixed and we told our customer to update to the 
latest release (contains at least fix for 61101) to get the “Vary: Origin” 
header of which absence they complained about.

But we were still getting complaints from the customer, and looking at the 
source code it seems “Vary: Origin” is only set if the request contains an 
origin header. I don’t believe this is sufficient. The spec states:

6.4 Implementation Considerations
This section is non-normative.
Resources that wish to enable themselves to be shared with multiple Origins but 
do not respond uniformly with "*" must in practice generate the 
Access-Control-Allow-Origin header dynamically in response to every request 
they wish to allow. As a consequence, authors of such resources should send a 
Vary: Origin HTTP header or provide other appropriate control directives to 
prevent caching of such responses, which may be inaccurate if re-used 
across-origins.

So if the same resource is accessed without origin (CORSRequestType.NOT_CORS) 
or origin is local (also CORSRequestType.NOT_CORS, i.e. the origin is discarded 
right now and no Vary: Origin set) and later with non-local origin, a caching 
layer in between can still be confused.
Even worse, there are user agents (Edge, older Firefox) that do html form posts 
w/o origin header at all and thus could be actively used to poison the cache 
(aside from doing worse to the servlet handling the call): 
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10482384/

A confused/poisoned cache will return the local origin response to all callers 
thus effectively denying any non-local client access since the access control 
headers will be missing. This has affected people before:
- https://bugs.chromium.org/p/chromium/issues/detail?id=409090
- 
https://stackoverflow.com/questions/44800431/caching-effect-on-cors-no-access-control-allow-origin-header-is-present-on-th

I believe that for all URLs the CorsFilter matches, any unique Origin header’s 
value is a variant, since the returned access control headers differ. But also 
its absence is a variant (allowed headers are missing altogether) and thus 
warrants a “Vary: Origin”. I.e. always set this header unless it’s an invalid 
CORS request. I had to write a little filter that is configured next to the 
CorsFilter and checks for the missing “Vary: Origin” header to add it when 
being called by CorsFilter in the filter chain.


That aside, setting “Vary: Origin” is of course very bad for caching. But then 
the CorsFilter should probably only be mapped to APIs called remotely.
As improvement, since with Bug 62343 allowed.origins = ‘*’ will always set 
Access-Control-Allow-Origin to '*', if any origin is allowed the filter could 
help caching by:
- always setting the access control response headers, i.e. even if not a CORS 
request (should not have negative effects)
- not setting “Vary: Origin”
This would probably greatly improve caching for public APIs that do not rely on 
credentials.
Kind of discussed here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=443530 

A single allowed origin is similar, but alas Access-Control-Allow-Origin 
headers will differ for this origin and the local origin (set to allowed host / 
missing) and thus cannot be improved the same way.

Sincerely,
Gunnar Brand

--
Gunnar Brand | Softwareentwickler
interface projects GmbH | www.intergator.de
Zwinglistraße 11/13 | 01277 Dresden | Deutschland
Tel: +49-351-31809-41 | Fax: +49-351-31809-33

Folgen Sie intergator auf:
Twitter : https://twitter.com/intergator
xing    : https://www.xing.com/companies/interfaceprojectsgmbh
LinkedIn: http://www.linkedin.com/company/interface-projects-gmbh
YouTube : http://www.youtube.com/user/TheEnterpriseSearch?feature=watch
Facebook: https://www.facebook.com/intergator/
RSS     : https://www.intergator.de/feed/

Geschäftsführer: Dr. Uwe Crenze, Eduard Daoud
Amtsgericht Dresden HRB 8740

Haftungsausschluss / Disclaimer
http://www.intergator.de/email-disclaimer.shtml




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to