diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs index d94b57c5b825a0..8161d1a8198659 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs @@ -269,5 +269,42 @@ await LoopbackServer.CreateServerAsync(async (origServer, origUrl) => }); } } + + [Theory] + [InlineData("ftp://ftp.example.com/file.txt")] + [InlineData("file:///etc/passwd")] + [InlineData("gopher://gopher.example.com")] + [InlineData("telnet://telnet.example.com")] + public async Task GetAsync_AllowAutoRedirectTrue_UnsupportedRedirectScheme_ReturnsOriginalResponse(string redirectLocation) + { + HttpClientHandler handler = CreateHttpClientHandler(); + handler.AllowAutoRedirect = true; + using (HttpClient client = CreateHttpClient(handler)) + { + await LoopbackServer.CreateServerAsync(async (server, url) => + { + Task getTask = client.GetAsync(url); + Task> serverTask = server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Found, $"Location: {redirectLocation}\r\n"); + + if (IsWinHttpHandler) + { + // WinHttpHandler throws HttpRequestException for unsupported redirect schemes + await Assert.ThrowsAsync(async () => await getTask); + await serverTask; + } + else + { + // SocketsHttpHandler refuses to follow the redirect and returns the original response + await TestHelper.WhenAllCompletedOrAnyFailed(getTask, serverTask); + + using (HttpResponseMessage response = await getTask) + { + Assert.Equal(302, (int)response.StatusCode); + Assert.Equal(url, response.RequestMessage.RequestUri); + } + } + }); + } + } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs index bd8710f367b114..20bf795b7a215a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs @@ -141,6 +141,17 @@ internal override async ValueTask SendAsync(HttpRequestMess return null; } + // Disallow automatic redirection to unsupported schemes + if (!HttpUtilities.IsSupportedScheme(location.Scheme)) + { + if (NetEventSource.Log.IsEnabled()) + { + TraceError($"Redirect from '{requestUri}' to '{location}' blocked due to unsupported scheme '{location.Scheme}'.", response.RequestMessage!.GetHashCode()); + } + + return null; + } + return location; }