diff --git a/va/http.go b/va/http.go index 5a944b4a8..bc75a9f58 100644 --- a/va/http.go +++ b/va/http.go @@ -505,6 +505,11 @@ func (va *ValidationAuthorityImpl) processHTTPValidation( numRedirects++ va.metrics.http01Redirects.Inc() + // If the response contains an HTTP 303 redirect, do not follow. + if req.Response.StatusCode == 303 { + return berrors.ConnectionFailureError("Cannot follow HTTP 303 redirects") + } + // Lowercase the redirect host immediately, as the dialer and redirect // validation expect it to have been lowercased already. req.URL.Host = strings.ToLower(req.URL.Host) diff --git a/va/http_test.go b/va/http_test.go index c8716f9cf..99368bbc3 100644 --- a/va/http_test.go +++ b/va/http_test.go @@ -570,6 +570,16 @@ func httpTestSrv(t *testing.T) *httptest.Server { fmt.Fprint(resp, "sorry, I'm gone") }) + // A path that always responds with a 303 redirect + mux.HandleFunc("/other", func(resp http.ResponseWriter, req *http.Request) { + http.Redirect( + resp, + req, + "http://example.org/other", + http.StatusSeeOther, + ) + }) + tooLargeBuf := bytes.NewBuffer([]byte{}) for i := 0; i < maxResponseSize+10; i++ { tooLargeBuf.WriteByte(byte(97)) @@ -925,6 +935,22 @@ func TestFetchHTTP(t *testing.T) { }, }, }, + { + Name: "HTTP status code 303 redirect", + Host: "example.com", + Path: "/other", + ExpectedProblem: probs.ConnectionFailure( + "Fetching http://example.org/other: Cannot follow HTTP 303 redirects"), + ExpectedRecords: []core.ValidationRecord{ + { + Hostname: "example.com", + Port: strconv.Itoa(httpPort), + URL: "http://example.com/other", + AddressesResolved: []net.IP{net.ParseIP("127.0.0.1")}, + AddressUsed: net.ParseIP("127.0.0.1"), + }, + }, + }, { Name: "Response too large", Host: "example.com",