aspnet / BasicMiddleware

[Archived] Basic middleware components for ASP.NET Core. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
169 stars 84 forks source link

IPv4 to IPv6 Mapped Addresses not mapped to IPv4 when checking known proxies/networks #358

Closed SebastianC closed 6 years ago

SebastianC commented 6 years ago

My scenario:

My problem:

Proposed fix:

This solution seems like it would also resolve another issue: #341 - "::ffff:127.0.0.1 not recognized as trusted local proxy"

Tratcher commented 6 years ago

One trouble with this is that people have been adding the IPv6 versions as a workaround. Changing it internally will break them unless you also change the KnownNetworks values for them.

SebastianC commented 6 years ago

I had originally considered updating another property to ForwardedHeadersOptions to indicate that this conversion should be turned "on", and default it to "off". Would that resolve your concern?

If it's a KnownProxy, I can see how adding the mapped-value would work, but i was unable to create a KnownNetwork that would be matched appropriately.

SebastianC commented 6 years ago

My apologies for the spam, but another option would be to check both variations:

        private bool CheckKnownAddress(IPAddress address)
        {
            if (address.IsIPv4MappedToIPv6)
            {
                var ipv4Address = address.MapToIPv4();
                if (_options.KnownProxies.Contains(ipv4Address))
                {
                    return true;
                }
                foreach (var network in _options.KnownNetworks)
                {
                    if (network.Contains(ipv4Address))
                    {
                        return true;
                    }
                }
            }
            if (_options.KnownProxies.Contains(address))
            {
                return true;
            }
            foreach (var network in _options.KnownNetworks)
            {
                if (network.Contains(address))
                {
                    return true;
                }
            }
            return false;
        }
Tratcher commented 6 years ago

Checking both varians is a good mitigation.

How's this for a simplification?

        private bool CheckKnownAddress(IPAddress address)
        {
            if (address.IsIPv4MappedToIPv6)
            {
                var ipv4Address = address.MapToIPv4();
                if (CheckKnownAddress(ipv4Address))
                {
                   return true;
                }
            }

            if (_options.KnownProxies.Contains(address))
            {
                return true;
            }

            foreach (var network in _options.KnownNetworks)
            {
                if (network.Contains(address))
                {
                    return true;
                }
            }
            return false;
        }
SebastianC commented 6 years ago

Better than mine. Will update the PR.