Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AllowOriginRequestFunc considered harmful (may lead to Web cache poisoning) #157

Closed
jub0bs opened this issue Aug 17, 2023 · 2 comments
Closed

Comments

@jub0bs
Copy link
Contributor

jub0bs commented Aug 17, 2023

PR #60 introduced AllowOriginRequestFunc, a field on cors.Options that lets users specify a custom function of the following signature:

func (r *http.Request, origin string) bool

As indicated by test cases that were added at the same time, motivations for this feature include the desire to vary responses on the basis of the presence and/or value of some request headers (e.g. Authorization):

AllowOriginRequestFunc: func(r *http.Request, o string) bool {
  return regexp.MustCompile("^http://foo").MatchString(o) &&
    r.Header.Get("Authorization") == "secret"
}

(Let's ignore the expensive regexp re-compilation at each invocation of the resulting CORS middleware and the excessive permissiveness of the regexp in question, here.)

Unfortunately, as I've written elsewhere, AllowOriginRequestFunc opens the door to Web cache poisoning:

If you vary responses on the basis of the presence and/or value of some request header, HTTP indeed mandates that you list the name of that header in your responses' Vary header; doing this signals to caching intermediaries that the header in question should be part of the cache key. But because the predicate lacks a http.ResponseWriter parameter, it gives you no way of populating the Vary header as required! You have to remember to manually do so outside of the predicate, somehow. If you forget, as I believe most developers do, to adequately populate the Vary header, caching intermediaries are then liable to serve inappropriate (and possibly malicious) cached responses to your clients.

For example, in the test case mentioned above, the response to an authenticated request (one containing request header Authorization: secret) may well get cached and subsequently get served by Web caches as a response to unauthenticated requests... 😬

To rule out Web cache poisoning, AllowOriginRequestFunc should provide rs/cors users a way to populate the Vary header accordingly. Note that this would require changing the type of that field, which would be a breaking change.

@rs rs closed this as completed in 6599721 Sep 5, 2023
@rs
Copy link
Owner

rs commented Sep 5, 2023

There is a new AllowOriginVaryRequestFunc that will update the Vary and an update to the doc saying to use it if headers are used for the condition. I can't remove the other option as it would be a breaking change.

@jub0bs
Copy link
Contributor Author

jub0bs commented Sep 5, 2023

@rs I can't think of a way to fix AllowOriginRequestFunc without triggering a major-version bump either. The best thing you can do is deprecate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants