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
net/http: client does not send cookies if an intermediary request hits a different domain #25465
Comments
After further investigation I noticed that this can be handled by overwriting the |
@arekkas - As per the documentation, it seems to me that this is intended, and changing this is possibly going to break behavior. /cc @bradfitz /@tombergan |
We discussed this in the Gopher slack too. While it is (obviously) required for the client to not send any confidential data across domains, the client should be able to send confidential data to the domain that data belongs to, regardless of prior redirects. Let's assume I have cookies for domain a and domain b. If I call domain a which redirects me to domain b, then domain a should get the proper credentials as should domain b. To me it appears to be nonsensical to strip cookies for domain b just because there was a prior redirect. You will not find a single browser that implements this behvaiour (stripping cookies due to redirects). |
And it is possible to do that, the following code has serious security issues as it sends confidential data across domains and has unexpected behaviour too. However, I want to prove my point that the data is there and it can actually be implemented without a lot of refactoring (imo): resp, err := (&http.Client{
Jar: c,
// Hack to fix cookie across domains
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) > 0 && req.Header.Get("cookie") == "" {
req.Header.Set("Cookie", via[len(via)-1].Header.Get("Cookie"))
}
return nil
},
}) |
If it turns out to be not accepted due to concerns of being a breaking change, we could probably supply another |
Seems fixable (making sure we set/get cookies from the |
/cc @vdobler too |
The gist provided to recreate the issue uses both For a cookiejar.Jar these are two different domains. @arekkas Could you provide a working example of the issue |
|
No they are not. See RFC 6265 section 1 third paragraph:
But localhost and 127.0.0.1 are considered different domains. Can you provide sample code which shows the claimed issue? |
I didn't know that! It doesn't affect the issue though and the issue in Go actually affects different ports as well.
I updated the opening post to better reflect the issue. The code represents the issue as intended. |
This works as expected, see code example at https://play.golang.org/p/p7io33sGrOa |
I think everything expected to work actually does so. |
Sorry for the post spam.
I'm rolling back this statement, the issue only affects if the domains are different - not the ports. Sorry for the confusion here! |
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 What happens instead is that, if I have a cookie jar with cookies for From the opening post:
I hope this clarifies the confusion. |
I do understand what you are trying so say and I do understand the scenario You claim that in step 5 the cookies for domain-a are missing and this claim Now it can happen that I made a mistake and that is why I ask you to The gist you provided is not a suitable evidence for your claim because Please try it out. Everything works exactly like you think it should, including |
You are right, please excuse that I didn't properly check the messy code I wrote. I refactored, cleaned and used stdlib only in a new example (here) and it works as expected (the cookie is being set). I tried it in different configurations (one mux on the same port but different domains, two muxs on different ports on different domains) without luck (wrt reproducing the initial issue). I'll close this for now and will come back to it if I can figure out what initially caused this mess. Please accept my apologies for spamming your (probably already very busy) inboxes with a non-issue and thank you all for the time put into trying to resolve this. |
@arekkas No need to apologize, this happens :-) I'm glad it is working now. |
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:
http://domain-a/set
http://domain-a/set
sets a Cookie and redirects tohttp://domain-b/foo
http://domain-b/foo
does nothing except redirecting back tohttp://domain-a/check
http://domain-a/check
is missing the cookieThe cookie is set if we do not redirect to
http://domain-b
but directly tohttp://domain-a
:http://domain-a/set
http://domain-a/set
sets a Cookie and redirects tohttp://domain-a/check
http://domain-a/check
has the cookie setA reproducible demo is available on gist.
I believe that this is caused by some logic that is tied to:
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 domainlocalhost: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.
The text was updated successfully, but these errors were encountered: