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?

To work around Vary Origin header in apps needing CORS, I should:

View Results

Loading ... Loading ...
2 comments on “CORS’ing the complexity: idempotent and caching meets Vary: Origin for CORS
  1. db Jayme Snyder says:

    What of the cache control response headers?

  2. db db says:

    turns out that doesn’t matter… this is a decision made client-side. The ‘vary: origin’ instructs the client to consider origin in its ‘cache-key’.

Leave a Reply to db Cancel reply

Your email address will not be published. Required fields are marked *

*