diff options
author | Morris Jobke <hey@morrisjobke.de> | 2018-10-30 10:49:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-30 10:49:08 +0100 |
commit | dccfe4bf8410b2c24c2568c249e76270ed050eb1 (patch) | |
tree | 0e14de612eb7440f616e10574340d2e4f7d4cbfc /lib | |
parent | c9e6a9963760403fe16c55e53937243563e9fa75 (diff) | |
parent | 401ca28f0773787146186bd568fd7901029dc5cd (diff) | |
download | nextcloud-server-dccfe4bf8410b2c24c2568c249e76270ed050eb1.tar.gz nextcloud-server-dccfe4bf8410b2c24c2568c249e76270ed050eb1.zip |
Merge pull request #12036 from olivermg/master
Add capability of specifying "trusted_proxies" entries in CIDR notation (IPv4)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/AppFramework/Http/Request.php | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 1d5a29f74f9..2c745973ed2 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -599,6 +599,44 @@ class Request implements \ArrayAccess, \Countable, IRequest { } /** + * Checks if given $remoteAddress matches given $trustedProxy. + * If $trustedProxy is an IPv4 IP range given in CIDR notation, true will be returned if + * $remoteAddress is an IPv4 address within that IP range. + * Otherwise $remoteAddress will be compared to $trustedProxy literally and the result + * will be returned. + * @return boolean true if $remoteAddress matches $trustedProxy, false otherwise + */ + protected function matchesTrustedProxy($trustedProxy, $remoteAddress) { + $cidrre = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\/([0-9]{1,2})$/'; + + if (preg_match($cidrre, $trustedProxy, $match)) { + $net = $match[1]; + $shiftbits = min(32, max(0, 32 - intval($match[2]))); + $netnum = ip2long($net) >> $shiftbits; + $ipnum = ip2long($remoteAddress) >> $shiftbits; + + return $ipnum === $netnum; + } + + return $trustedProxy === $remoteAddress; + } + + /** + * Checks if given $remoteAddress matches any entry in the given array $trustedProxies. + * For details regarding what "match" means, refer to `matchesTrustedProxy`. + * @return boolean true if $remoteAddress matches any entry in $trustedProxies, false otherwise + */ + protected function isTrustedProxy($trustedProxies, $remoteAddress) { + foreach ($trustedProxies as $tp) { + if ($this->matchesTrustedProxy($tp, $remoteAddress)) { + return true; + } + } + + return false; + } + + /** * Returns the remote address, if the connection came from a trusted proxy * and `forwarded_for_headers` has been configured then the IP address * specified in this header will be returned instead. @@ -609,7 +647,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { $remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; $trustedProxies = $this->config->getSystemValue('trusted_proxies', []); - if(\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies)) { + if(\is_array($trustedProxies) && $this->isTrustedProxy($trustedProxies, $remoteAddress)) { $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [ 'HTTP_X_FORWARDED_FOR' // only have one default, so we cannot ship an insecure product out of the box |