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