cors

CORS’ing the complexity: idempotent and caching meets Vary: Origin for CORS


So I spent a bit of time debugging something this am, and I thought I would share. Its super detailed, so feel free to gloss over.

There is a class of browser-security issues addressed by CORS. They are meant to prevent inadvertent (or malicious) cross-origin resource sharing. E.g. some javascript in your current web page posts a password.

I am using Istio. It magically takes the CORS origin and rewrites it. So if you do a:

GET /
Origin: foo

then it will respond:

200 OK
Access-Control-Allow-Origin: *

*if* its configured for ‘*’ policy.

Now, the problem is, I have two clients that are using OpenID Connect. They are fetching the keys for jwks validation. They run in the same browser. One of them does:

GET /keys
Origin: app-1

the other does

GET /keys
Origin: app-2

Unfortunately, the browser *caches* the 2nd response, returning the response app-1 got (with the wrong Access-Control-Allow-Origin) in it.

Why? Well, let’s dive into some specs. Here we find the answer.

If CORS protocol requirements are more complicated than setting `Access-Control-Allow-Origin` to * or a static origin, `Vary` is to be used. [HTML] [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]

Huh. I’m supposed to add a ‘Vary’ header to these. But, sadly, I am not in control of these applications. What is one to do? RTFC for envoy?