Skip to content

Commit a7b1801

Browse files
committed
net/http: prevent incorrect redirections when the path contains %2F%2F
The current implementation of ServeMux incorrectly returns a 301 status code when the path contains URL-encoded data, and especially URL-encoded URLs. Fixes golang#21955
1 parent 4ec4a79 commit a7b1801

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/net/http/serve_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ func TestServeWithSlashRedirectForHostPatterns(t *testing.T) {
553553
mux.Handle("example.com:3000/pkg/connect/", stringHandler("example.com:3000/pkg/connect/"))
554554
mux.Handle("example.com:9000/", stringHandler("example.com:9000/"))
555555
mux.Handle("/pkg/baz/", stringHandler("/pkg/baz/"))
556+
mux.Handle("example.com/r/", stringHandler("example.com/r/https%3A%2F%2Fgoogle.com"))
556557

557558
tests := []struct {
558559
method string
@@ -562,11 +563,13 @@ func TestServeWithSlashRedirectForHostPatterns(t *testing.T) {
562563
want string
563564
}{
564565
{"GET", "http://example.com/", 404, "", ""},
566+
{"GET", "http://example.com//", 301, "http://example.com/", ""},
565567
{"GET", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""},
566568
{"GET", "http://example.com/pkg/bar", 200, "", "example.com/pkg/bar"},
567569
{"GET", "http://example.com/pkg/bar/", 200, "", "example.com/pkg/bar/"},
568570
{"GET", "http://example.com/pkg/baz", 301, "/pkg/baz/", ""},
569571
{"GET", "http://example.com:3000/pkg/foo", 301, "/pkg/foo/", ""},
572+
{"GET", "http://example.com/r/https%3A%2F%2Fgoogle.com", 200, "", "example.com/r/https%3A%2F%2Fgoogle.com"},
570573
{"CONNECT", "http://example.com/", 404, "", ""},
571574
{"CONNECT", "http://example.com:3000/", 404, "", ""},
572575
{"CONNECT", "http://example.com:9000/", 200, "", "example.com:9000/"},

src/net/http/server.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,18 +2334,23 @@ func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
23342334
return mux.handler(r.Host, r.URL.Path)
23352335
}
23362336

2337+
rawPath := r.URL.RawPath
2338+
if rawPath == "" {
2339+
rawPath = r.URL.Path
2340+
}
2341+
23372342
// All other requests have any port stripped and path cleaned
23382343
// before passing to mux.handler.
23392344
host := stripHostPort(r.Host)
2340-
path := cleanPath(r.URL.Path)
2345+
path := cleanPath(rawPath)
23412346

23422347
// If the given path is /tree and its handler is not registered,
23432348
// redirect for /tree/.
23442349
if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok {
23452350
return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
23462351
}
23472352

2348-
if path != r.URL.Path {
2353+
if path != rawPath {
23492354
_, pattern = mux.handler(host, path)
23502355
url := *r.URL
23512356
url.Path = path

0 commit comments

Comments
 (0)