expressjs/cors

`Vary: Origin` should be set on non-CORS request

Open

#330 opened on Oct 18, 2024

View on GitHub
 (2 comments) (1 reaction) (0 assignees)JavaScript (5,897 stars) (476 forks)batch import
3.xbughelp wanted

Description

By default, the Vary: Origin response header is set, which is good. However, it is not set if the Origin request header is missing (i.e. on non-CORS requests).

https://github.com/expressjs/cors/blob/53312a5bee605e2486fa734756abb3c0bc2f891d/lib/index.js#L220-L222

That's an error as mentioned in the standard.

In particular, consider what happens if Vary is not used and a server is configured to send Access-Control-Allow-Origin for a certain resource only in response to a CORS request. When a user agent receives a response to a non-CORS request for that resource (for example, as the result of a navigation request), the response will lack Access-Control-Allow-Origin and the user agent will cache that response. Then, if the user agent subsequently encounters a CORS request for the resource, it will use that cached response from the previous non-CORS request, without Access-Control-Allow-Origin.

But if Vary: Origin is used in the same scenario described above, it will cause the user agent to fetch a response that includes Access-Control-Allow-Origin, rather than using the cached response from the previous non-CORS request that lacks Access-Control-Allow-Origin.

Also in this blog post.

The rule here is simple: If your server makes a decision about what to return based on a what’s in a HTTP header, you need to include that header name in your Vary, even if the request didn’t include that header.

One thing to add here: if the Origin request header is ignored when computing any CORS response, then Vary: Origin should not be set (regardless of whether the Origin request header was used or not). In practice, this is when the origin option is false or a string (the default value), as opposed to when it is true, a regular expression, an array or a function. (see #332).

Contributor guide