Skip to content

Commit 16940c3

Browse files
CopilotMihaZupan
andauthored
Add URL scheme validation for HTTP redirects in SocketsHttpHandler (#121263)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: MihaZupan <[email protected]>
1 parent 0e0759a commit 16940c3

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AutoRedirect.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,5 +269,42 @@ await LoopbackServer.CreateServerAsync(async (origServer, origUrl) =>
269269
});
270270
}
271271
}
272+
273+
[Theory]
274+
[InlineData("ftp://ftp.example.com/file.txt")]
275+
[InlineData("file:///etc/passwd")]
276+
[InlineData("gopher://gopher.example.com")]
277+
[InlineData("telnet://telnet.example.com")]
278+
public async Task GetAsync_AllowAutoRedirectTrue_UnsupportedRedirectScheme_ReturnsOriginalResponse(string redirectLocation)
279+
{
280+
HttpClientHandler handler = CreateHttpClientHandler();
281+
handler.AllowAutoRedirect = true;
282+
using (HttpClient client = CreateHttpClient(handler))
283+
{
284+
await LoopbackServer.CreateServerAsync(async (server, url) =>
285+
{
286+
Task<HttpResponseMessage> getTask = client.GetAsync(url);
287+
Task<List<string>> serverTask = server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Found, $"Location: {redirectLocation}\r\n");
288+
289+
if (IsWinHttpHandler)
290+
{
291+
// WinHttpHandler throws HttpRequestException for unsupported redirect schemes
292+
await Assert.ThrowsAsync<HttpRequestException>(async () => await getTask);
293+
await serverTask;
294+
}
295+
else
296+
{
297+
// SocketsHttpHandler refuses to follow the redirect and returns the original response
298+
await TestHelper.WhenAllCompletedOrAnyFailed(getTask, serverTask);
299+
300+
using (HttpResponseMessage response = await getTask)
301+
{
302+
Assert.Equal(302, (int)response.StatusCode);
303+
Assert.Equal(url, response.RequestMessage.RequestUri);
304+
}
305+
}
306+
});
307+
}
308+
}
272309
}
273310
}

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ internal override async ValueTask<HttpResponseMessage> SendAsync(HttpRequestMess
141141
return null;
142142
}
143143

144+
// Disallow automatic redirection to unsupported schemes
145+
if (!HttpUtilities.IsSupportedScheme(location.Scheme))
146+
{
147+
if (NetEventSource.Log.IsEnabled())
148+
{
149+
TraceError($"Redirect from '{requestUri}' to '{location}' blocked due to unsupported scheme '{location.Scheme}'.", response.RequestMessage!.GetHashCode());
150+
}
151+
152+
return null;
153+
}
154+
144155
return location;
145156
}
146157

0 commit comments

Comments
 (0)