From bc528cf8cdf42f09187b1ed34bc29d27c97ca5fc Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 15 Apr 2020 13:44:26 -0700 Subject: [PATCH] Error when redirect target is too long. (#4775) This can happen when a misconfiguration redirects a certain path to itself, doubled. After 10 redirects the error message can get quite long. Instead we halt things at 2000 bytes, which should be more than enough. --- va/http.go | 9 ++++++++- va/http_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/va/http.go b/va/http.go index 43e92ced8..7f8eab6e2 100644 --- a/va/http.go +++ b/va/http.go @@ -28,8 +28,11 @@ const ( // HTTP-01 challenge response. The expected payload should be ~87 bytes. Since // it may be padded by whitespace which we previously allowed accept up to 128 // bytes before rejecting a response (32 byte b64 encoded token + . + 32 byte - // b64 encoded key fingerprint) + // b64 encoded key fingerprint). maxResponseSize = 128 + // maxPathSize is the maximum number of bytes we will accept in the path of a + // redirect URL. + maxPathSize = 2000 // whitespaceCutset is the set of characters trimmed from the right of an // HTTP-01 key authorization response. whitespaceCutset = "\n\r\t " @@ -521,6 +524,10 @@ func (va *ValidationAuthorityImpl) processHTTPValidation( } redirPath := req.URL.Path + if len(redirPath) > maxPathSize { + return berrors.ConnectionFailureError("Redirect target too long") + } + // If the redirect URL has query parameters we need to preserve // those in the redirect path redirQuery := "" diff --git a/va/http_test.go b/va/http_test.go index 0a59c9879..027fca89f 100644 --- a/va/http_test.go +++ b/va/http_test.go @@ -558,6 +558,14 @@ func httpTestSrv(t *testing.T) *httptest.Server { fmt.Fprint(resp, tooLargeBuf) }) + mux.HandleFunc("/redir-path-too-long", func(resp http.ResponseWriter, req *http.Request) { + http.Redirect( + resp, + req, + "https://example.com/this-is-too-long-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", + http.StatusMovedPermanently) + }) + // A path that redirects to an uppercase public suffix (#4215) mux.HandleFunc("/redir-uppercase-publicsuffix", func(resp http.ResponseWriter, req *http.Request) { http.Redirect( @@ -811,6 +819,22 @@ func TestFetchHTTP(t *testing.T) { }, }, }, + { + Name: "Redirect to long path", + Host: "example.com", + Path: "/redir-path-too-long", + ExpectedProblem: probs.ConnectionFailure( + "Fetching https://example.com/this-is-too-long-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789: Redirect target too long"), + ExpectedRecords: []core.ValidationRecord{ + { + Hostname: "example.com", + Port: strconv.Itoa(httpPort), + URL: "http://example.com/redir-path-too-long", + AddressesResolved: []net.IP{net.ParseIP("127.0.0.1")}, + AddressUsed: net.ParseIP("127.0.0.1"), + }, + }, + }, { Name: "Wrong HTTP status code", Host: "example.com",