Handle IPv4ToIPv6 Mapped Addresses when checking known proxies/networks (#359)

* Un-Map IPv4-to-IPv6-Mapped ips before comparing to known proxies/networks. Addresses #358

* Checking both mapped and unmapped versions of IPv4toIPv6 ips. Addresses #358

* Confirm IPv4toIPv6 mapping/unmapping. Addresses #358
This commit is contained in:
Sebastian 2018-09-07 17:02:31 -04:00 committed by Chris Ross
parent b0d334af1c
commit d36dcca713
2 changed files with 51 additions and 0 deletions

View File

@ -349,6 +349,14 @@ namespace Microsoft.AspNetCore.HttpOverrides
private bool CheckKnownAddress(IPAddress address)
{
if (address.IsIPv4MappedToIPv6)
{
var ipv4Address = address.MapToIPv4();
if (CheckKnownAddress(ipv4Address))
{
return true;
}
}
if (_options.KnownProxies.Contains(address))
{
return true;

View File

@ -822,5 +822,48 @@ namespace Microsoft.AspNetCore.HttpOverrides
Assert.Equal("localhost", context.Request.Host.ToString());
Assert.Equal("Protocol", context.Request.Scheme);
}
[Theory]
[InlineData("22.33.44.55,::ffff:127.0.0.1", "", "", "22.33.44.55")]
[InlineData("22.33.44.55,::ffff:172.123.142.121", "172.123.142.121", "", "22.33.44.55")]
[InlineData("22.33.44.55,::ffff:172.123.142.121", "::ffff:172.123.142.121", "", "22.33.44.55")]
[InlineData("22.33.44.55,::ffff:172.123.142.121,172.32.24.23", "", "172.0.0.0/8", "22.33.44.55")]
[InlineData("2a00:1450:4009:802::200e,2a02:26f0:2d:183::356e,::ffff:172.123.142.121,172.32.24.23", "", "172.0.0.0/8,2a02:26f0:2d:183::1/64", "2a00:1450:4009:802::200e")]
[InlineData("22.33.44.55,2a02:26f0:2d:183::356e,::ffff:127.0.0.1", "2a02:26f0:2d:183::356e", "", "22.33.44.55")]
public async Task XForwardForIPv4ToIPv6Mapping(string forHeader, string knownProxies, string knownNetworks, string expectedRemoteIp)
{
var options = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor,
ForwardLimit = null,
};
foreach (var knownProxy in knownProxies.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
var proxy = IPAddress.Parse(knownProxy);
options.KnownProxies.Add(proxy);
}
foreach (var knownNetwork in knownNetworks.Split(new string[] { "," }, options:StringSplitOptions.RemoveEmptyEntries))
{
var knownNetworkParts = knownNetwork.Split('/');
var networkIp = IPAddress.Parse(knownNetworkParts[0]);
var prefixLength = int.Parse(knownNetworkParts[1]);
options.KnownNetworks.Add(new IPNetwork(networkIp, prefixLength));
}
var builder = new WebHostBuilder()
.Configure(app =>
{
app.UseForwardedHeaders(options);
});
var server = new TestServer(builder);
var context = await server.SendAsync(c =>
{
c.Request.Headers["X-Forwarded-For"] = forHeader;
});
Assert.Equal(expectedRemoteIp, context.Connection.RemoteIpAddress.ToString());
}
}
}