diff options
| author | Damien Neil <dneil@google.com> | 2023-08-07 15:57:54 -0700 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2023-08-08 23:10:58 +0000 |
| commit | 2d5ce9b729c0edded841301bd73d68d5e95aa28b (patch) | |
| tree | 11d113ee1e8e538124cdea6b2953c8eff3bf5e12 /src/net/http | |
| parent | 6e43407931ee4acc204620a9fae59c7903164901 (diff) | |
| download | go-2d5ce9b729c0edded841301bd73d68d5e95aa28b.tar.xz | |
net/http: sanitize User-Agent header in request writer
Apply the same transformations to the User-Agent header value that we
do to other headers.
Avoids header and request smuggling in Request.Write and
Request.WriteProxy. RoundTrip already validates values in
Request.Header, and didn't allow bad User-Agent values to
make it as far as the request writer.
Fixes #61824
Change-Id: I360a915c7e08d014e0532bd5af196a5b59c89395
Reviewed-on: https://go-review.googlesource.com/c/go/+/516836
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/net/http')
| -rw-r--r-- | src/net/http/request.go | 2 | ||||
| -rw-r--r-- | src/net/http/request_test.go | 19 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go index d1fbd5df90..0fb73c12b5 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -669,6 +669,8 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF userAgent = r.Header.Get("User-Agent") } if userAgent != "" { + userAgent = headerNewlineToSpace.Replace(userAgent) + userAgent = textproto.TrimString(userAgent) _, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent) if err != nil { return err diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go index a32b583c11..5711164894 100644 --- a/src/net/http/request_test.go +++ b/src/net/http/request_test.go @@ -787,6 +787,25 @@ func TestRequestBadHostHeader(t *testing.T) { } } +func TestRequestBadUserAgent(t *testing.T) { + got := []string{} + req, err := NewRequest("GET", "http://foo/after", nil) + if err != nil { + t.Fatal(err) + } + req.Header.Set("User-Agent", "evil\r\nX-Evil: evil") + req.Write(logWrites{t, &got}) + want := []string{ + "GET /after HTTP/1.1\r\n", + "Host: foo\r\n", + "User-Agent: evil X-Evil: evil\r\n", + "\r\n", + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Writes = %q\n Want = %q", got, want) + } +} + func TestStarRequest(t *testing.T) { req, err := ReadRequest(bufio.NewReader(strings.NewReader("M-SEARCH * HTTP/1.1\r\n\r\n"))) if err != nil { |
