Skip to content

Always set Vary: Origin when reflecting the request Origin - #267

Open
arpitjain099 wants to merge 1 commit into
gorilla:mainfrom
arpitjain099:chore/always-vary-origin
Open

Always set Vary: Origin when reflecting the request Origin#267
arpitjain099 wants to merge 1 commit into
gorilla:mainfrom
arpitjain099:chore/always-vary-origin

Conversation

@arpitjain099

Copy link
Copy Markdown

When the CORS middleware reflects the caller's Origin back into Access-Control-Allow-Origin, the response depends on that origin, so a shared cache in front of the app needs Vary: Origin to key on it. Right now that header is only set when more than one static origin is configured (len(ch.allowedOrigins) > 1). The common credentialed setups do not hit that branch:

  • a single AllowedOrigins([]string{"https://app.example.com"})
  • an AllowedOriginValidator (the usual way to allow a set of dynamic/subdomain origins with credentials)

In both cases the middleware echoes the request Origin (often alongside Access-Control-Allow-Credentials: true) but sends no Vary. A cache sitting in front of the app can then store one origin's response and hand it to a request from a different origin, which is the classic CORS cache-poisoning shape.

The fix sets Vary: Origin whenever a non-wildcard origin is reflected. rs/cors and go-chi/cors both do this on every reflected response. The wildcard * answer is identical for every origin, so it still gets no Vary: Origin; that keeps the behavior that #114 tried to change and #122 deliberately reverted. Preflight responses also derive Access-Control-Allow-Methods / Access-Control-Allow-Headers from the request's Access-Control-Request-* headers, so those are added to Vary on the OPTIONS path too.

Tests: added cases asserting Vary: Origin is present for the single-origin and validator (credentialed) configs and that preflight varies on the request method/headers, plus a case asserting the wildcard answer still does not add Vary: Origin. The existing multi-origin and star tests still pass. go test ./... is green; without the fix the three new reflected-origin tests fail because Vary is empty.

When the CORS middleware echoes the caller's Origin back into
Access-Control-Allow-Origin (with a single configured origin, or an
AllowedOriginValidator, which is the usual credentialed multi-origin
setup), the response depends on the request Origin. But Vary: Origin was
only emitted when more than one static origin was configured, so most
reflected responses told shared caches they do not vary by Origin. A
cache in front of the app can then serve one origin's credentialed CORS
response to a request from another origin.

Set Vary: Origin whenever a non-wildcard Origin is reflected, matching
rs/cors and go-chi/cors. The wildcard "*" answer is identical for every
origin and still gets no Vary: Origin, so the case reverted in gorilla#122 is
unaffected. Preflight responses also derive Allow-Methods/Allow-Headers
from the request's Access-Control-Request-* headers, so those are added
to Vary as well.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant