gocookiesdouble-quotes

Go: how to not remove double quotes on cookies


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:

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: "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


Solution

  • 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:

    HTTP RFC 7230 3.2.6.

    These characters are included for quoted-string:

    HTAB, SP !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ %x80-FF

    The characters " and / may be included if escaped.