Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "3rdparty"]
path = 3rdparty
url = https://github.com/nextcloud/3rdparty.git
url = https://github.com/johanfleury/3rdparty.git
branch = feature/vendor-rlanvin-php-ip
2 changes: 1 addition & 1 deletion 3rdparty
53 changes: 26 additions & 27 deletions lib/private/AppFramework/Http/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use OCP\IRequest;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use IPBlock;

/**
* Class for accessing variables in the request.
Expand Down Expand Up @@ -599,36 +600,34 @@ public function getId(): string {
}

/**
* 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
* Checks if $remoteAddress matches an entry in $trustedProxies.
*
* An address is considered to be matching if it is present in the
* table or part of a subnet present in the table.
*
* @param array $trustedProxies an array of IPv4 or IPv6 addresses or
* subnets (in CIRD notation)
*
* @param string $remoteAddress an IPv4 or IPv6 address
*
* @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)) {
$subnet = null;

try {
# The prefix parameter of IPBlock::create act
# as a default value for when prefix is not
# specified in $tp.
$subnet = IPBlock::create($tp, '32');
} catch (InvalidArgumentException $e) {
# That should be logged somehow
continue;
}

if ($subnet && $subnet->contains($remoteAddress)) {
return true;
}
}
Expand Down