-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: invalid byte '"' in Cookie.Value; dropping invalid bytes #18627
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
Please attach a code sample that shows the problem.
…On Thu, 12 Jan 2017, 18:18 sinylei ***@***.***> wrote:
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (go version)?
go root# go version
go version go1.7.1 darwin/amd64
What operating system and processor architecture are you using (go env)?
root# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.1/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments
-fmessage-length=0 -fdebug-prefix-map=/tmp/go-build065605285=/tmp/go-build
-gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
What did you do?
Hi,
I am trying to access a Web server using net/http.
But the request was rejected by the server due to the cookie not accepted,
missing a pair of "".
My application report in console log as below:
net/http: invalid byte '"' in Cookie.Value; dropping invalid bytes
The cookie I sent in my request looks like this:
Cookie:
_LSID=2543ebb4-1213-47f8-b31a-a17a31ec93d3,Fy4oMdFmUw5wt1vD/gm0jDBV3hje6omX1VDusKRcf/Bj5Qenv4uTaPE2pRWvt7JNXyO0bFdrQfd0w4TYzxIXGQ==
The cookie required and accepted by server:
cookie:
_LSID="2543ebb4-1213-47f8-b31a-a17a31ec93d3,Fy4oMdFmUw5wt1vD/gm0jDBV3hje6omX1VDusKRcf/Bj5Qenv4uTaPE2pRWvt7JNXyO0bFdrQfd0w4TYzxIXGQ=="
The difference is a pair of char(") at the both sides of the Cookie value
string.
What did you expect to see?
Could you remove the Cookie Value authentication for char '"'
What did you see instead?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#18627>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAcAxwPjr0i2-RUX813ZWcCil88Rvr7ks5rRdPJgaJpZM4LhcVu>
.
|
See also #7243 which discusses these restrictions on cookie values. |
import (
"github.com/mozillazg/request"
"net/http"
)
func checkServer(user) {
c := &http.Client{}
req := request.NewRequest(c)
req.Cookies = map[string]string {
// "_LSID" : user.LSID,
"_LSID" : `"` + user.LSID + `"`,
}
...
} My code looks above using a third package request which is a wrapper of original net/http. The server which is out of my control requires the cookie as below. The server requires Double quotes in the cookie value and mandatory. |
@sinylei i meant a code sample that compiled. |
@davecheney sorry, I can not provide you a code sample since it is not a standalone app, it is a subsystem of a project, which is original written by nodejs. Now I am trying to rewrite some subsystem using golang to improve the performance. I understand that golang has the restrictions on cookie value to avoid any potential security issue for server-side application developed by golang. But for the client application, the language should provide the developer flexibility on cookie values that required by some server. Actually, nodejs has no such restrictions on cookie values. I read the source code of net/http and found the restriction is here: |
The cookies with quoted values added via package main
import (
"fmt"
"log"
"net/http"
"net/http/httptest"
"net/http/httputil"
)
func main() {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
data, _ := httputil.DumpRequest(r, false)
fmt.Println(string(data))
}))
c := http.Cookie{
Name: "name1",
Value: `"quoted"`,
Path: "/",
}
r, _ := http.NewRequest("GET", s.URL, nil)
r.AddCookie(&c)
r.Header.Add("Cookie", `name2="quoted"`)
_, err := http.DefaultClient.Do(r)
if err != nil {
log.Fatal(err)
}
} Output:
|
If Go is violating RFCs, somebody should cite which RFCs we're violating, and then we can fix. If Go is not violating RFCs, somebody should provide evidence that the RFCs are wrong (that popular clients & servers behave otherwise, reliably, with details). Then we can file bugs against the RFCs and add workarounds. |
According to the RFC 6265 section 4.1.1,
where DQUOTE is a double quote. So double-quoted cookie values are explicitly allowed. |
@opennota, yes, but Are you saying that this bug is that Go should add double quotes around cookie values in more cases? |
No. I'm okay with the current behaviour, where one can send double quoted cookie values by adding them directly to the request headers. But at least nodejs (as the reporter says) behaves differently. How about other languages and platforms? |
Perhaps Go could recognize and do not remove double quotes around the cookie values in |
@opennota You provide a really good workaround, that put such quoted string into Header portion. Header related function does not do such value validation. Thank you very much! |
Previous discussion was in #7243. The Go code is currently: // http://tools.ietf.org/html/rfc6265#section-4.1.1
// 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
// We loosen this as spaces and commas are common in cookie values
// but we produce a quoted cookie-value in when value starts or ends
// with a comma or space.
// See https://golang.org/issue/7243 for the discussion.
func sanitizeCookieValue(v string) string {
v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v)
if len(v) == 0 {
return v
}
if v[0] == ' ' || v[0] == ',' || v[len(v)-1] == ' ' || v[len(v)-1] == ',' {
return `"` + v + `"`
}
return v
} It sounds like this bug is suggesting that we need to double-quote the Set-Cookie value on the wire in more cases. Perhaps if there's a comma anywhere in the value string. |
It is really a good workaround, put quoted cookies in Header since Header related function does not do such cookie value validation.
Cookie is part of HTTP Header.
@opennota Many many thanks.
… 在 2017年1月13日,上午9:30,opennota ***@***.*** ***@***.***>> 写道:
The cookies with quoted values added via AddCookie are unquoted, those added via Header.Add are not.
package main
import (
"fmt"
"log"
"net/http"
"net/http/httptest"
"net/http/httputil"
)
func main() {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
data, _ := httputil.DumpRequest(r, false)
fmt.Println(string(data))
}))
c := http.Cookie{
Name: "name1",
Value: `"quoted"`,
Path: "/",
}
r, _ := http.NewRequest("GET", s.URL, nil)
r.AddCookie(&c)
r.Header.Add("Cookie", `name2="quoted"`)
_, err := http.DefaultClient.Do(r)
if err != nil {
log.Fatal(err)
}
}
Output:
2017/01/13 08:28:38 net/http: invalid byte '"' in Cookie.Value; dropping invalid bytes
GET / HTTP/1.1
Host: 127.0.0.1:42767
Accept-Encoding: gzip
Cookie: name1=quoted
Cookie: name2="quoted"
User-Agent: Go-http-client/1.1
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#18627 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AX6WMmjDYRPt1P78ljowPwtVjneJtZ5qks5rRtOYgaJpZM4LhcVu>.
|
@odeke-em, you interested in this one? |
Say no more fam, I got it. |
@odeke-em, still got it? :) |
Yap yap, I'll work on it tonight after this lab exercise ie in about 4 hours and send in a CL, otherwise I'll ping you for help. |
So am interpreting this issue differently, and we have 2 different options:
// 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 That is: if a cookie value has double quotes, they must be in pairs surrounding a cookie octet. What do y'all think? 1. Is trivial. 2. requires a bit more of cleverness but I've implemented it as well. EDIT: Just to be clear, with 2. The qualm code in this issue will be accepted |
I've mailed https://go-review.googlesource.com/c/36642. |
CL https://golang.org/cl/36642 mentions this issue. |
Am I mistaken, or you code assumes that |
@opennota let's comment on the CL :) but cookie-octet in my CL cannot be a double quote, it can be the empty string surrounded by a pair of double quotes e.g "" but not """. |
I just don't get this |
Yes you are right, after doing a second reading of the definition, I see that I might have misinterpreted the definition: I read |
The cookie-value in question is
which consists of valid cookie-octets and an invalid internal comma ",". This comma is illegal according to RFC 6265 in a cookie value, be it unquoted or quoted. RFC 6265 never requires double quoting cookie values.
We decided to allow formally malformed cookie values with spaces and commas and send them in quoted form iff required by browsers (i.e. leading or trailing), but send internal spaces/commas unquoted. It seems as if there are clients out in the wild which require the cookie-values to be quoted also for internal commas (and probably spaces). Formally there is no bug as commas are disallowed in cookie-values by RFC 6265. Alternatives are:
|
Sorry but why not? |
@vdobler, option (3) sounds good to me. |
we should handle cookies like what browsers do not RFCs
|
|
i tested some cases with chrome and firefox
Note: |
CL https://golang.org/cl/37328 mentions this issue. |
@ddo Chrome is very liberal in some regards, Firefox in others (e.g. UTF-8 values). If only Chrome had to be supported it would be easy. |
@vdobler I'll let you take over the CL, as I don't seem to fully understand the deeper problem. Thanks for looking into it. |
Still having that issue, Microsoft is using JSON in a cookie value as well, using double quotes. While I did code a workaround (extracting the raw value from the header), is there some way to supress the error message? |
@JamesCullum please open a new issue, this one is closed. |
What version of Go are you using (
go version
)?go root# go version
go version go1.7.1 darwin/amd64
What operating system and processor architecture are you using (
go env
)?root# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.1/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build065605285=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
What did you do?
Hi,
I am trying to access a Web server using net/http.
But the request was rejected by the server due to the cookie not accepted, missing a pair of "".
My application report in console log as below:
net/http: invalid byte '"' in Cookie.Value; dropping invalid bytes
The cookie I sent in my request looks like this:
Cookie: _LSID=2543ebb4-1213-47f8-b31a-a17a31ec93d3,Fy4oMdFmUw5wt1vD/gm0jDBV3hje6omX1VDusKRcf/Bj5Qenv4uTaPE2pRWvt7JNXyO0bFdrQfd0w4TYzxIXGQ==
The cookie required and accepted by server:
cookie: _LSID="2543ebb4-1213-47f8-b31a-a17a31ec93d3,Fy4oMdFmUw5wt1vD/gm0jDBV3hje6omX1VDusKRcf/Bj5Qenv4uTaPE2pRWvt7JNXyO0bFdrQfd0w4TYzxIXGQ=="
The difference is a pair of char(") at the both sides of the Cookie value string.
What did you expect to see?
Could you remove the Cookie Value authentication for char '"'
What did you see instead?
The text was updated successfully, but these errors were encountered: