From d36dcca7134541e610d2ddaf2083a5495ffc0920 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 7 Sep 2018 17:02:31 -0400 Subject: [PATCH] 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 --- .../ForwardedHeadersMiddleware.cs | 8 ++++ .../ForwardedHeadersMiddlewareTest.cs | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs b/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs index decda81d58..e6eeaa5e98 100644 --- a/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs +++ b/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs @@ -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; diff --git a/test/Microsoft.AspNetCore.HttpOverrides.Tests/ForwardedHeadersMiddlewareTest.cs b/test/Microsoft.AspNetCore.HttpOverrides.Tests/ForwardedHeadersMiddlewareTest.cs index f88243c9e7..5f18bf4574 100644 --- a/test/Microsoft.AspNetCore.HttpOverrides.Tests/ForwardedHeadersMiddlewareTest.cs +++ b/test/Microsoft.AspNetCore.HttpOverrides.Tests/ForwardedHeadersMiddlewareTest.cs @@ -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()); + } } }