-
Notifications
You must be signed in to change notification settings - Fork 18.1k
net/http: isCookieNameValid in net/http/cookie.go seems overly restrictive #29580
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
Comments
/cc @bradfitz |
@dprime You can manually handle these types of cookies: |
I just checked:
allow this type of cookie name name. (With Opera being based on Chromium this was expected.) |
@vdobler Ah, of course, fair point. I was forgetting you don't have to use a cookie jar, it's possible to manually handle the Set-Cookie responses and set the outbound Cookie header directly. The default impl of the cookie jar can't handle these names at all, though. |
@dprime I might misremember the details but net/http/cookiejar.Jar should be agnostic to the names. I think you can you the default Jar and populate it with SetCookies and retrieve the cookies with Cookies. Of course you loos the automatic integration with the Client, but if you manually parse the Set-Cookie header, you can construct a Cookie, store that in in a Jar with SetCookies and retrieve it back with Cookies. Now create a Cookie header manually from that Cookie. |
There's a decent writeup here of the state of cookie names: https://stackoverflow.com/questions/1969232/allowed-characters-in-cookies Perhaps we should just copy whatever firefox or chromium do? |
I'm afraid of opening a can of worms: If we are going to "fix" this we probably have to abandon any spec and just accept everything. Treat (Set-)Cookie headers as UTF-8 encoded and allow anything in name and value, maybe even '=' in values. Adding to the mess people do with cookies "because it works in my browser". I would suggest "won't fix" as not broken. |
I would say that's a reasonable way of thinking about it. However "because it works in my browser" here is equivalent to "this is how pretty much 100% of people currently access http services". Your proposed "fix" is obviously too far - the mozilla spec I linked to is pretty much the standard RFC for tokens in http plus a couple of extras and is likely what Chrome et al use as well. There is no need for this to be a binary situation of perfect spec adherence or utter chaos. There is an accepted, real world, broad usage of the middle ground. The specs and reality disagree here. |
@dprime The Mozilla spec you linked (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives) clearly forbids the use of Browsers are very lax. If I read the Chromium tests in https://chromium.googlesource.com/chromium/src.git/+/master/net/cookies/parsed_cookie_unittest.cc correctly than Chromium will accept stuff like If you know of any document which describes what you call "accepted, real world, broad usage of the middle ground" I would be happy if you could provide a copy or a link to it. Your "middle ground" is muddy: While all agree that you cannot have
|
Can somebody (@dprime ??) figure out what Firefox and Chromium actually do in terms of code (and what they still reject)? You linked to a Mozilla spec, above, but as @vdobler said, if Mozilla (Firefox) accepts |
I did some test how browser (Chrome, Safari, Opera; all on Mac) handle cookies with names containing (or consisting of) formally forbidden characters: The following octets may be part of a cookie-name in all three browsers:
The cookie name may start with, end with, contain or consist solely of these characters. All three browser agree on the handling of 0x3d "=": A cookie name may not start with an equal sign if followed by an allowed characters (but a single = as name is okay; very strange). Handling between browsers differs for these octets:
Using UTF-8 encoded runes >= U+0080 in a cookie-name works for Chrome but not in Safari. (None of the three browser allows 0x3b ";" as part of the cookie-name and none allows octets < 0x20.) If someone wants to test different browser or different platforms I can supply the code used to test it. |
I had problems regarding brackets in cookie name. I've created a PR which should fix it golang/net#33. Brackets are commonly used as a simulation of arrays and to handle it I had to split the required header by myself (for now). |
As it isn't explicitly mentioned so far, I'll add a reference to RFC 6265, HTTP State Management Mechanism: https://tools.ietf.org/html/rfc6265 IIRC, it isn't symmetric on the production versus parsing of Set-Cookie and Cookie headers. I'd argue that Go's stdlib makes the right thing easy, and the wrong thing possible, and that's good enough. Postel was wrong, and Go's stdlib weakening its RFC compliance yet further is a bad idea: https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00#section-1 |
@RalphCorderoy Thanks for providing the "Postel was wrong" document! But as explained above: Even if Postel would not have been wrong we simply cannot be lax during accepting cookies and strict while sending: The whole purpose of a cookie is to be roundtripped back and forth between client and server. I see just two options.
I'm in favour of 1. @bkielbasa I do not think that the use of [ and ] in JavaScript code is a strong argument for allowing them: Plain JavaScript code can use whatever works in the browser but if some JavaScript code intends to have the cookies sent back to the server and processed there, the JavaScript code should stick to well formed cookies only. |
Go version: 1.20 I just wanted to add that I too have just run into this and it is extremely frustrating. I now have to write a bunch of additional code and error checking to properly handle cookies, basically re-implementing the cookiejar module because it silently ignores any malformed cookie. While I understand the desire to adhere to specs and do things the "right" way, the fact of the matter is that reality is chaos and I have to write software that handles reality, not just things that adhere to a spec. I can't control what other websites name their cookies, but I still need to store and use them regardless. There is no way to even know that things are being ignored because the cookiejar doesn't even have a way to propagate errors, which is another pain point entirely. |
Uh oh!
There was an error while loading. Please reload this page.
Note: I attempted to post this to the golang nuts list, but my message was rejected twice for unspecified reasons.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Code in current https://github.com/golang/go/blob/master/src/net/http/cookie.go is the same as my release.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Set-Cookie: ISAWPLB{48BCE7DA-ADD0-4237-A5B8-816663CFDD23}={70F05AF6-A2D2-4861-9D98-B73CEF42E642}; HttpOnly; Path=/
What did you expect to see?
I expected the http package to tolerate sloppy cookie names that exist in the wild on the internet and are supported by all major browsers. This cookie name works on firefox and chrome latest. I've not tested with anything else, but given my local council is using it, and it's produced by a Microsoft application stack, I suspect it works everywhere.
What did you see instead?
net/http/client.go attempts to handle the Set-Cookie header by calling net/http/cookie.go readSetCookies() , but fails silently, swallowing the Set-Cookie without any warning, because it deems the cookie name
ISAWPLB{48BCE7DA-ADD0-4237-A5B8-816663CFDD23}
invalid because it contains, as far as I can tell,{
and}
.This actually means that it's impossible for me to use go (without hacking net/http) to communicate properly with this web server, because the stringer on a Cookie returns "" unless the name is valid, which stops the cookie being included with outbound requests. So, even if I manually handled this badly named cookie, the http client will refuse to send it, regardless.
The text was updated successfully, but these errors were encountered: