go: net/http: client does not send cookies if an intermediary request hits a different domain

What version of Go are you using (go version)?

1.10.2

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Windows 10 and OSX

What did you do?

I have the following scenario:

  1. HTTP Client makes a request to http://domain-a/set
  2. HTTP Handler at http://domain-a/set sets a Cookie and redirects to http://domain-b/foo
  3. HTTP Handler at http://domain-b/foo does nothing except redirecting back to http://domain-a/check
  4. HTTP Header at http://domain-a/check is missing the cookie

The cookie is set if we do not redirect to http://domain-b but directly to http://domain-a:

  1. HTTP Client makes a request to http://domain-a/set
  2. HTTP Handler at http://domain-a/set sets a Cookie and redirects to http://domain-a/check
  3. HTTP Header at http://domain-a/check has the cookie set

A reproducible demo is available on gist.

I believe that this is caused by some logic that is tied to:

// • when forwarding sensitive headers like “Authorization”, // “WWW-Authenticate”, and “Cookie” to untrusted targets. // These headers will be ignored when following a redirect to a domain // that is not a subdomain match or exact match of the initial domain. // For example, a redirect from “foo.com” to either “foo.com” or “sub.foo.com” // will forward the sensitive headers, but a redirect to “bar.com” will not.

My intuition tells me that the cookie header is deleted if the client encounters a domain that does not match the original domain, and does not recover the cookie in subsequent redirects if the domain is set back to the original one.

From what I can tell, this behaviour could be caused by shouldCopyHeaderOnRedirect which strips all the info and thus makes it unavailable in subsequent requests.

What did you expect to see?

I expected the cookie to be available at localhost:9000 (this is not about the intermediary domain localhost:8000), even if one of the redirects (in the middle) is a different domain. This is the default behavior of browsers too.

What did you see instead?

The cookie was not set.


edit://

While this is an edge case, it is kind of common in scenarios with federation where the browser does a lot of redirects between domains. That’s actually how I found this issue.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 18 (8 by maintainers)

Most upvoted comments

@arekkas No need to apologize, this happens 😃 I’m glad it is working now.

Feel free to use whatever ports you like but make sure that you do not expect cookies for localhost to appear on 127.0.0.1

I think there is a misunderstanding here. I’ll try to be as concise as possible in the description.

I have a cookie jar that has cookies for domain-a. I expect that these cookies are always sent to domain-a when making a request to domain-a, regardless of any prior redirections.

What happens instead is that, if I have a cookie jar with cookies for domain-a, the cookies will be stripped if - somewhere inbetween - a request to another domain (e.g. domain-b) was made.

From the opening post:

  1. HTTP Client makes a request to http://domain-a/set. (Here, a cookie for domain-a will be set in the cookiejar).
  2. HTTP Handler at http://domain-a/set sets a Cookie and redirects to http://domain-b/foo
  3. HTTP Request is sent to http://domain-b/foo. No cookies are included. This is expected and required and ok.
  4. HTTP Handler at http://domain-b/foo does nothing except redirecting back to http://domain-a/check
  5. HTTP Header at http://domain-a/check is missing the the cookie from the cookie jar for domain-a. (Here, we’d expect the cookies for domain-a to be included because the prior redirection should not affect whether or not legitimate cookies are sent to domain-a or not. The proper cookies should always be included in requests to domain-a if the cookies are in fact set for domain-a)

I hope this clarifies the confusion.

Seems fixable (making sure we set/get cookies from the Jar per request across redirects), but not for Go 1.11.