Description
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)?