Go removes double quotes in cookies. Is there a way to keep double quotes in cookies in Go?
For example, I'm sending a small JSON message and "SetCookie" strips double quote.
w.SetCookie("my_cookie_name", small_json_message)
More about Cookies:
The HTTP RFC defines quoted string values. See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6
The proposed cookie RFC explicitly says double quotes are allowed in cookie values: cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
;
is the cookie delimiter.
Values with ASCII characters outside the limited ASCII range may be quoted (The RFC calls this the quoted_string
) which expands the allowed character set.
JSON does not contain the ;
character, so for ;
to appear in JSON it can only appear in string values. In JSON, string values are already quoted.
I've confirmed testing using a simple k:v JSON payload and it works fine on all major browsers with no issues. Of course, the payload cannot be arbitrary, and must be constrained to cookies.
Cookies are typically generated by server data, not user data. This means well structured, not arbitrary, JSON may be used
Go currently has a condition to insert double quote into cookies.
JSON easily can conform to the cookie RFC. Additionally, even though it's not an issue with this example of JSON, regarding the hypothetical concern of not conforming to the RFC:
Sec-Ch-Ua
header created by Chrome, includes several "bad" characters.Sec-Ch-Ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
For reference, here's the relevant section of RFC 6265
set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
Where one can see whitespace DQUOTE
is disallowed and DQUOTE
is allowed.
For example, from the author of the RFC,
Set-Cookie: foo="bar"
results in a cookie
Cookie: foo="bar"
3 4
Yes. Double quotes are allowed in cookies and other HTTP headers. Double quotes are also used to escape characters that would be otherwise invalid.
Here's a way to manually set a cookie, where w
is the http.responseWriter and b
is the bytes of the cookie. Max-Age is in seconds and 999999999 is ~31.69 years.
w.Header().Set("Set-Cookie", "your_cookie_name="+string(b)+"; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict")
Since you'll probably use cURL to test sending cookies to the server, here's a useful test:
curl --insecure --cookie 'test1={"test1":"v1"}; test2={"test2":"v2"}' https://localhost:8081/
Which results in a HTTP header like the following:
GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={"test1":"v1"}; test2={"test2":"v2"}
User-Agent: curl/7.0.0
Although not the case here and the above is compliant with the RFC, many of the RFC rules are ignored all the time, especially commas. For example, Chrome sets this header:
Sec-Ch-Ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
Gasp! Is uses commas and other things! It is well established that commas in HTTP headers are okay, even though the RFC appears to say otherwise.
Note that the Chrome header uses spaces, many double quotes, commas, special characters, and semi colon. Chrome here uses double quotes around many values needing escaping, and that's the right way to be compliant with the RFC.
Note that the cookie RFC 6265 is a proposal and has been for 11 years. There are reasons for that. Knowing that cookies are just a HTTP header, look at the accepted HTTP RFC for quoted string semantic for header values:
These characters are included for quoted-string
:
HTAB, SP !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ %x80-FF
The characters " and / may be included if escaped.