testing IP exemption, handle corner cases found in testing

This commit is contained in:
El RIDO 2021-05-22 10:59:47 +02:00
parent 89f6f0051d
commit 3dd01b1f70
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
6 changed files with 40 additions and 35 deletions

View file

@ -25,7 +25,7 @@
}, },
"require" : { "require" : {
"php" : "^5.6.0 || ^7.0 || ^8.0", "php" : "^5.6.0 || ^7.0 || ^8.0",
"paragonie/random_compat" : "2.0.19", "paragonie/random_compat" : "2.0.20",
"yzalis/identicon" : "2.0.0", "yzalis/identicon" : "2.0.0",
"mlocati/ip-lib" : "1.14.0" "mlocati/ip-lib" : "1.14.0"
}, },

12
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c3aa7487ba976536cd3db9a60473ce67", "content-hash": "217f0ba9bdac1014a332a8ba390be949",
"packages": [ "packages": [
{ {
"name": "mlocati/ip-lib", "name": "mlocati/ip-lib",
@ -76,16 +76,16 @@
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v2.0.19", "version": "v2.0.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/random_compat.git", "url": "https://github.com/paragonie/random_compat.git",
"reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0f1f60250fccffeaf5dda91eea1c018aed1adc2a",
"reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -121,7 +121,7 @@
"pseudorandom", "pseudorandom",
"random" "random"
], ],
"time": "2020-10-15T10:06:57+00:00" "time": "2021-04-17T09:33:01+00:00"
}, },
{ {
"name": "yzalis/identicon", "name": "yzalis/identicon",

View file

@ -121,20 +121,23 @@ class TrafficLimiter extends AbstractPersistence
$address = \IPLib\Factory::addressFromString($_SERVER[self::$_ipKey]); $address = \IPLib\Factory::addressFromString($_SERVER[self::$_ipKey]);
$range = \IPLib\Factory::rangeFromString(trim($ipRange)); $range = \IPLib\Factory::rangeFromString(trim($ipRange));
// If $range is null something went wrong (possible invalid ip given in config). It's here becaue matches($range) does not accepts null vallue // address could not be parsed, we might not be in IP space and try a string comparison instead
if ($address == null) {
return $_SERVER[self::$_ipKey] === $ipRange;
}
// range could not be parsed, possibly an invalid ip range given in config
if ($range == null) { if ($range == null) {
return false; return false;
} }
// Ip-lib does throws and exception when something goes wrong, if so we want to catch it and set contained to false // Ip-lib throws an exception when something goes wrong, if so we want to catch it and set contained to false
try { try {
return $address->matches($range); return $address->matches($range);
} catch (\Exception $e) { } catch (\Exception $e) {
// If something is wrong with matching the ip, we do nothing // If something is wrong with matching the ip, we assume it doesn't match
}
return false; return false;
} }
}
/** /**
* traffic limiter * traffic limiter

View file

@ -35,5 +35,20 @@ class TrafficLimiterTest extends PHPUnit_Framework_TestCase
$this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass'); $this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass');
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$this->assertFalse(TrafficLimiter::canPass(), 'fifth request is to fast, may not pass'); $this->assertFalse(TrafficLimiter::canPass(), 'fifth request is to fast, may not pass');
// exempted IPs configuration
TrafficLimiter::setExemptedIp('1.2.3.4,10.10.10.0/24,2001:1620:2057::/48');
$this->assertFalse(TrafficLimiter::canPass(), 'still too fast and not exempted');
$_SERVER['REMOTE_ADDR'] = '10.10.10.10';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in exempted range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv4 in exempted range');
$_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in exempted range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv6 in exempted range');
TrafficLimiter::setExemptedIp('127.*,foobar');
$this->assertFalse(TrafficLimiter::canPass(), 'request is to fast, invalid range');
$_SERVER['REMOTE_ADDR'] = 'foobar';
$this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but non-IP address matches exempted range');
} }
} }

View file

@ -54,9 +54,9 @@ if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
$RandomCompatDIR = dirname(__FILE__); $RandomCompatDIR = dirname(__FILE__);
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'byte_safe_strings.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php';
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'cast_to_int.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php';
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'error_polyfill.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php';
if (!is_callable('random_bytes')) { if (!is_callable('random_bytes')) {
/** /**
@ -76,9 +76,9 @@ if (!is_callable('random_bytes')) {
if (extension_loaded('libsodium')) { if (extension_loaded('libsodium')) {
// See random_bytes_libsodium.php // See random_bytes_libsodium.php
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium.php';
} elseif (method_exists('Sodium', 'randombytes_buf')) { } elseif (method_exists('Sodium', 'randombytes_buf')) {
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium_legacy.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium_legacy.php';
} }
} }
@ -117,7 +117,7 @@ if (!is_callable('random_bytes')) {
// place, that is not helpful to us here. // place, that is not helpful to us here.
// See random_bytes_dev_urandom.php // See random_bytes_dev_urandom.php
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_dev_urandom.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_dev_urandom.php';
} }
// Unset variables after use // Unset variables after use
$RandomCompat_basedir = null; $RandomCompat_basedir = null;
@ -159,7 +159,7 @@ if (!is_callable('random_bytes')) {
extension_loaded('mcrypt') extension_loaded('mcrypt')
) { ) {
// See random_bytes_mcrypt.php // See random_bytes_mcrypt.php
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_mcrypt.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_mcrypt.php';
} }
$RandomCompatUrandom = null; $RandomCompatUrandom = null;
@ -182,9 +182,10 @@ if (!is_callable('random_bytes')) {
if (!in_array('com', $RandomCompat_disabled_classes)) { if (!in_array('com', $RandomCompat_disabled_classes)) {
try { try {
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
/** @psalm-suppress TypeDoesNotContainType */
if (method_exists($RandomCompatCOMtest, 'GetRandom')) { if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
// See random_bytes_com_dotnet.php // See random_bytes_com_dotnet.php
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_com_dotnet.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php';
} }
} catch (com_exception $e) { } catch (com_exception $e) {
// Don't try to use it. // Don't try to use it.
@ -219,7 +220,7 @@ if (!is_callable('random_bytes')) {
} }
if (!is_callable('random_int')) { if (!is_callable('random_int')) {
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_int.php'; require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php';
} }
$RandomCompatDIR = null; $RandomCompatDIR = null;

View file

@ -1,14 +0,0 @@
<?php
require_once __DIR__ . '/psalm-autoload.php';
/**
* This is necessary for PHPUnit on PHP >= 5.3
*
* Class PHPUnit_Framework_TestCase
*/
if (PHP_VERSION_ID >= 50300) {
if (!class_exists('PHPUnit_Framework_TestCase')) {
require_once __DIR__ . '/other/phpunit-shim.php';
}
}