From a7b18017a26f7bb0ccbced91f055124082245a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 20 May 2020 12:26:41 +0200 Subject: [PATCH] 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 #21955 --- src/net/http/serve_test.go | 3 +++ src/net/http/server.go | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index 5f5693277828b3..d47e0cf7f7aabd 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -553,6 +553,7 @@ func TestServeWithSlashRedirectForHostPatterns(t *testing.T) { mux.Handle("example.com:3000/pkg/connect/", stringHandler("example.com:3000/pkg/connect/")) mux.Handle("example.com:9000/", stringHandler("example.com:9000/")) mux.Handle("/pkg/baz/", stringHandler("/pkg/baz/")) + mux.Handle("example.com/r/", stringHandler("example.com/r/https%3A%2F%2Fgoogle.com")) tests := []struct { method string @@ -562,11 +563,13 @@ func TestServeWithSlashRedirectForHostPatterns(t *testing.T) { want string }{ {"GET", "http://example.com/", 404, "", ""}, + {"GET", "http://example.com//", 301, "http://example.com/", ""}, {"GET", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""}, {"GET", "http://example.com/pkg/bar", 200, "", "example.com/pkg/bar"}, {"GET", "http://example.com/pkg/bar/", 200, "", "example.com/pkg/bar/"}, {"GET", "http://example.com/pkg/baz", 301, "/pkg/baz/", ""}, {"GET", "http://example.com:3000/pkg/foo", 301, "/pkg/foo/", ""}, + {"GET", "http://example.com/r/https%3A%2F%2Fgoogle.com", 200, "", "example.com/r/https%3A%2F%2Fgoogle.com"}, {"CONNECT", "http://example.com/", 404, "", ""}, {"CONNECT", "http://example.com:3000/", 404, "", ""}, {"CONNECT", "http://example.com:9000/", 200, "", "example.com:9000/"}, diff --git a/src/net/http/server.go b/src/net/http/server.go index b613c21f16ee29..097df72f195bfe 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -2334,10 +2334,15 @@ func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { return mux.handler(r.Host, r.URL.Path) } + rawPath := r.URL.RawPath + if rawPath == "" { + rawPath = r.URL.Path + } + // All other requests have any port stripped and path cleaned // before passing to mux.handler. host := stripHostPort(r.Host) - path := cleanPath(r.URL.Path) + path := cleanPath(rawPath) // If the given path is /tree and its handler is not registered, // redirect for /tree/. @@ -2345,7 +2350,7 @@ func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { return RedirectHandler(u.String(), StatusMovedPermanently), u.Path } - if path != r.URL.Path { + if path != rawPath { _, pattern = mux.handler(host, path) url := *r.URL url.Path = path