Skip to content

Commit 1cb6199

Browse files
Forwarded Headers Middleware: Ignore XForwardedHeaders from Unknown Proxy (#61530)
1 parent 995205f commit 1cb6199

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -220,19 +220,19 @@ public void ApplyForwarders(HttpContext context)
220220
for (; entriesConsumed < sets.Length; entriesConsumed++)
221221
{
222222
var set = sets[entriesConsumed];
223-
if (checkFor)
223+
// For the first instance, allow remoteIp to be null for servers that don't support it natively.
224+
if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address))
224225
{
225-
// For the first instance, allow remoteIp to be null for servers that don't support it natively.
226-
if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address))
226+
// Stop at the first unknown remote IP, but still apply changes processed so far.
227+
if (_logger.IsEnabled(LogLevel.Debug))
227228
{
228-
// Stop at the first unknown remote IP, but still apply changes processed so far.
229-
if (_logger.IsEnabled(LogLevel.Debug))
230-
{
231-
_logger.LogDebug(1, "Unknown proxy: {RemoteIpAndPort}", currentValues.RemoteIpAndPort);
232-
}
233-
break;
229+
_logger.LogDebug(1, "Unknown proxy: {RemoteIpAndPort}", currentValues.RemoteIpAndPort);
234230
}
231+
break;
232+
}
235233

234+
if (checkFor)
235+
{
236236
if (IPEndPoint.TryParse(set.IpAndPortText, out var parsedEndPoint))
237237
{
238238
applyChanges = true;

src/Middleware/HttpOverrides/test/ForwardedHeadersMiddlewareTest.cs

+73
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,79 @@ public async Task AllOptionsDisabledRequestDoesntChange()
962962
Assert.Equal(PathString.Empty, context.Request.PathBase);
963963
}
964964

965+
[Theory]
966+
[InlineData(ForwardedHeaders.XForwardedFor, false)]
967+
[InlineData(ForwardedHeaders.XForwardedFor, true)]
968+
[InlineData(ForwardedHeaders.XForwardedHost, false)]
969+
[InlineData(ForwardedHeaders.XForwardedHost, true)]
970+
[InlineData(ForwardedHeaders.XForwardedProto, false)]
971+
[InlineData(ForwardedHeaders.XForwardedProto, true)]
972+
[InlineData(ForwardedHeaders.XForwardedPrefix, false)]
973+
[InlineData(ForwardedHeaders.XForwardedPrefix, true)]
974+
public async Task IgnoreXForwardedHeadersFromUnknownProxy(ForwardedHeaders forwardedHeaders, bool unknownProxy)
975+
{
976+
using var host = new HostBuilder()
977+
.ConfigureWebHost(webHostBuilder =>
978+
{
979+
webHostBuilder
980+
.UseTestServer()
981+
.Configure(app =>
982+
{
983+
var options = new ForwardedHeadersOptions
984+
{
985+
ForwardedHeaders = forwardedHeaders
986+
};
987+
if (!unknownProxy)
988+
{
989+
var proxy = IPAddress.Parse("10.0.0.1");
990+
options.KnownProxies.Add(proxy);
991+
}
992+
app.UseForwardedHeaders(options);
993+
});
994+
}).Build();
995+
996+
await host.StartAsync();
997+
998+
var server = host.GetTestServer();
999+
1000+
var context = await server.SendAsync(c =>
1001+
{
1002+
c.Request.Headers["X-Forwarded-For"] = "11.111.111.11";
1003+
c.Request.Headers["X-Forwarded-Host"] = "testhost";
1004+
c.Request.Headers["X-Forwarded-Proto"] = "Protocol";
1005+
c.Request.Headers["X-Forwarded-Prefix"] = "/pathbase";
1006+
c.Connection.RemoteIpAddress = IPAddress.Parse("10.0.0.1");
1007+
c.Connection.RemotePort = 99;
1008+
});
1009+
1010+
if (unknownProxy)
1011+
{
1012+
Assert.Equal("10.0.0.1", context.Connection.RemoteIpAddress.ToString());
1013+
Assert.Equal("localhost", context.Request.Host.ToString());
1014+
Assert.Equal("http", context.Request.Scheme);
1015+
Assert.Equal(PathString.Empty, context.Request.PathBase);
1016+
}
1017+
else
1018+
{
1019+
if (forwardedHeaders.HasFlag(ForwardedHeaders.XForwardedFor))
1020+
{
1021+
Assert.Equal("11.111.111.11", context.Connection.RemoteIpAddress.ToString());
1022+
}
1023+
if (forwardedHeaders.HasFlag(ForwardedHeaders.XForwardedHost))
1024+
{
1025+
Assert.Equal("testhost", context.Request.Host.ToString());
1026+
}
1027+
if (forwardedHeaders.HasFlag(ForwardedHeaders.XForwardedProto))
1028+
{
1029+
Assert.Equal("Protocol", context.Request.Scheme);
1030+
}
1031+
if (forwardedHeaders.HasFlag(ForwardedHeaders.XForwardedPrefix))
1032+
{
1033+
Assert.Equal("/pathbase", context.Request.PathBase);
1034+
}
1035+
}
1036+
}
1037+
9651038
[Fact]
9661039
public async Task PartiallyEnabledForwardsPartiallyChangesRequest()
9671040
{

0 commit comments

Comments
 (0)