Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Bug determining isFromTrustedProxy as secure broadcasted proxies #24424

Closed
@webmake

Description

@webmake
Q A
Bug report? yes
Feature request? no
BC Break report? no
Symfony version 3.3.9

First all all bug recovered debugging https://github.com/fideloper/TrustedProxy, why all trafic is still under http, not https. So let's take a look.

    public function isSecure()
    {
        if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_CLIENT_PROTO)) {
            return in_array(strtolower($proto[0]), array('https', 'on', 'ssl', '1'), true);
        }

        $https = $this->server->get('HTTPS');

        return !empty($https) && 'off' !== strtolower($https);
    }

gives always as not secure (isSecure is false - that's not expected)

Okay Let's take then deeper. Called method isFromTrustedProxy gives false:

    public function isFromTrustedProxy()
    {
        return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies);
    }

Let's take some data that we set via setTrustedProxies, $proxies = ['*']. Now what's happening:

['*'] && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), ['*'])

first part is true (good), but checkIp returns false (not expected).

    public static function checkIp($requestIp, $ips)
    {
        if (!is_array($ips)) {
            $ips = array($ips);
        }

        $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';

        foreach ($ips as $ip) {
            if (self::$method($requestIp, $ip)) {
                return true;
            }
        }

        return false;
    }

So any ip, against all others '*' is not valid, strange. Now let's take real data:
$requestIp = 192.168.20.13, and $ip = '*'

    public static function checkIp4($requestIp, $ip)
    {
        $cacheKey = $requestIp.'-'.$ip;
        if (isset(self::$checkedIps[$cacheKey])) {
            return self::$checkedIps[$cacheKey];
        }

        if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            return self::$checkedIps[$cacheKey] = false;
        }

        if (false !== strpos($ip, '/')) {
            list($address, $netmask) = explode('/', $ip, 2);

            if ($netmask === '0') {
                return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
            }

            if ($netmask < 0 || $netmask > 32) {
                return self::$checkedIps[$cacheKey] = false;
            }
        } else {
            $address = $ip;
            $netmask = 32;
        }

        return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
    }

Description tells:

@return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet

Where am I wrong, giving all trafic as 0.0.0.0 or '*' (just to be clear

sprintf('%032b', ip2long('0.0.0.0')) and
sprintf('%032b', ip2long('*'))

are the same), but turns out that trusted all network (broadcast), not matches against given ip (192.168.20.13)?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions