diff --git a/composer.json b/composer.json index 98aaedde..a8e98aaa 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "require" : { "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", "mlocati/ip-lib" : "1.14.0" }, diff --git a/composer.lock b/composer.lock index 20b0732a..931c92fb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c3aa7487ba976536cd3db9a60473ce67", + "content-hash": "217f0ba9bdac1014a332a8ba390be949", "packages": [ { "name": "mlocati/ip-lib", @@ -76,16 +76,16 @@ }, { "name": "paragonie/random_compat", - "version": "v2.0.19", + "version": "v2.0.20", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0f1f60250fccffeaf5dda91eea1c018aed1adc2a", + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a", "shasum": "" }, "require": { @@ -121,7 +121,7 @@ "pseudorandom", "random" ], - "time": "2020-10-15T10:06:57+00:00" + "time": "2021-04-17T09:33:01+00:00" }, { "name": "yzalis/identicon", diff --git a/lib/Persistence/TrafficLimiter.php b/lib/Persistence/TrafficLimiter.php index af6e4979..612a1c91 100644 --- a/lib/Persistence/TrafficLimiter.php +++ b/lib/Persistence/TrafficLimiter.php @@ -121,19 +121,22 @@ class TrafficLimiter extends AbstractPersistence $address = \IPLib\Factory::addressFromString($_SERVER[self::$_ipKey]); $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) { 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 { return $address->matches($range); } 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; } /** diff --git a/tst/Persistence/TrafficLimiterTest.php b/tst/Persistence/TrafficLimiterTest.php index 73769380..41013016 100644 --- a/tst/Persistence/TrafficLimiterTest.php +++ b/tst/Persistence/TrafficLimiterTest.php @@ -35,5 +35,20 @@ class TrafficLimiterTest extends PHPUnit_Framework_TestCase $this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass'); $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $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'); } } diff --git a/vendor/paragonie/random_compat/lib/random.php b/vendor/paragonie/random_compat/lib/random.php index 36245f54..6df1cb0c 100644 --- a/vendor/paragonie/random_compat/lib/random.php +++ b/vendor/paragonie/random_compat/lib/random.php @@ -54,9 +54,9 @@ if (!defined('RANDOM_COMPAT_READ_BUFFER')) { $RandomCompatDIR = dirname(__FILE__); -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'byte_safe_strings.php'; -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'cast_to_int.php'; -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'error_polyfill.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php'; if (!is_callable('random_bytes')) { /** @@ -76,9 +76,9 @@ if (!is_callable('random_bytes')) { if (extension_loaded('libsodium')) { // See random_bytes_libsodium.php 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')) { - 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. // 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 $RandomCompat_basedir = null; @@ -159,7 +159,7 @@ if (!is_callable('random_bytes')) { extension_loaded('mcrypt') ) { // 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; @@ -182,9 +182,10 @@ if (!is_callable('random_bytes')) { if (!in_array('com', $RandomCompat_disabled_classes)) { try { $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); + /** @psalm-suppress TypeDoesNotContainType */ if (method_exists($RandomCompatCOMtest, 'GetRandom')) { // 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) { // Don't try to use it. @@ -219,7 +220,7 @@ if (!is_callable('random_bytes')) { } if (!is_callable('random_int')) { - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_int.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php'; } $RandomCompatDIR = null; diff --git a/vendor/paragonie/random_compat/phpunit-autoload.php b/vendor/paragonie/random_compat/phpunit-autoload.php deleted file mode 100644 index 87b01aac..00000000 --- a/vendor/paragonie/random_compat/phpunit-autoload.php +++ /dev/null @@ -1,14 +0,0 @@ -= 5.3 - * - * Class PHPUnit_Framework_TestCase - */ -if (PHP_VERSION_ID >= 50300) { - if (!class_exists('PHPUnit_Framework_TestCase')) { - require_once __DIR__ . '/other/phpunit-shim.php'; - } -}