Просмотр исходного кода

Merge branch 'api-ip-exempt' of https://github.com/rodehoed/PrivateBin into api-ip-exempt

LinQhost Managed hosting 5 лет назад
Родитель
Сommit
63d6816c7c
5 измененных файлов с 130 добавлено и 6 удалено
  1. 4 0
      cfg/conf.sample.php
  2. 3 2
      composer.json
  3. 69 1
      composer.lock
  4. 4 3
      lib/Configuration.php
  5. 50 0
      lib/Persistence/TrafficLimiter.php

+ 4 - 0
cfg/conf.sample.php

@@ -135,6 +135,10 @@ markdown = "Markdown"
 ; Set this to 0 to disable rate limiting.
 limit = 10
 
+; Set ips (v4|v6) which should be exempted for the rate-limit. CIDR also supported. Needed to be comma separated.
+; Unset for enabling and invalid values will be ignored
+; eg: exemptedIp = '1.2.3.4,10.10.10/24'
+
 ; (optional) if your website runs behind a reverse proxy or load balancer,
 ; set the HTTP header containing the visitors IP address, i.e. X_FORWARDED_FOR
 ; header = "X_FORWARDED_FOR"

+ 3 - 2
composer.json

@@ -26,7 +26,8 @@
 	"require" : {
 		"php" : "^5.6.0 || ^7.0 || ^8.0",
 		"paragonie/random_compat" : "2.0.19",
-		"yzalis/identicon" : "2.0.0"
+		"yzalis/identicon" : "2.0.0",
+		"mlocati/ip-lib": "^1.14"
 	},
 	"require-dev" : {
 		"phpunit/phpunit" : "^4.6 || ^5.0"
@@ -39,4 +40,4 @@
 	"config" : {
 		"autoloader-suffix" : "DontChange"
 	}
-}
+}

+ 69 - 1
composer.lock

@@ -4,8 +4,76 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "9d110873bf15a6abd66734e8a818134c",
+    "content-hash": "8138b0e4bb3fcaab9ca4c02bbe35d891",
     "packages": [
+        {
+            "name": "mlocati/ip-lib",
+            "version": "1.14.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mlocati/ip-lib.git",
+                "reference": "882bc0e115970a536b13bcfa59f312783fce08c8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mlocati/ip-lib/zipball/882bc0e115970a536b13bcfa59f312783fce08c8",
+                "reference": "882bc0e115970a536b13bcfa59f312783fce08c8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "ext-pdo_sqlite": "*",
+                "phpunit/dbunit": "^1.4 || ^2 || ^3 || ^4",
+                "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "IPLib\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michele Locati",
+                    "email": "mlocati@gmail.com",
+                    "homepage": "https://github.com/mlocati",
+                    "role": "Author"
+                }
+            ],
+            "description": "Handle IPv4, IPv6 addresses and ranges",
+            "homepage": "https://github.com/mlocati/ip-lib",
+            "keywords": [
+                "IP",
+                "address",
+                "addresses",
+                "ipv4",
+                "ipv6",
+                "manage",
+                "managing",
+                "matching",
+                "network",
+                "networking",
+                "range",
+                "subnet"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/mlocati",
+                    "type": "github"
+                },
+                {
+                    "url": "https://paypal.me/mlocati",
+                    "type": "other"
+                }
+            ],
+            "time": "2020-12-31T11:30:02+00:00"
+        },
         {
             "name": "paragonie/random_compat",
             "version": "v2.0.19",

+ 4 - 3
lib/Configuration.php

@@ -79,9 +79,10 @@ class Configuration
             'markdown'           => 'Markdown',
         ),
         'traffic' => array(
-            'limit'  => 10,
-            'header' => null,
-            'dir'    => 'data',
+            'limit'      => 10,
+            'header'     => null,
+            'dir'        => 'data',
+            'exemptedIp' => null,
         ),
         'purge' => array(
             'limit'     => 300,

+ 50 - 0
lib/Persistence/TrafficLimiter.php

@@ -1,4 +1,5 @@
 <?php
+
 /**
  * PrivateBin
  *
@@ -30,6 +31,15 @@ class TrafficLimiter extends AbstractPersistence
      */
     private static $_limit = 10;
 
+    /**
+     * listed ips are exempted from limits, defaults to null
+     *
+     * @access private
+     * @static
+     * @var    array
+     */
+    private static $_exemptedIp = null;
+
     /**
      * key to fetch IP address
      *
@@ -51,6 +61,18 @@ class TrafficLimiter extends AbstractPersistence
         self::$_limit = $limit;
     }
 
+    /**
+     * set a list of ip(ranges) as string
+     *
+     * @access public
+     * @static
+     * @param string $exemptedIps
+     */
+    public static function setExemptedIp($exemptedIp)
+    {
+        self::$_exemptedIp = $exemptedIp;
+    }
+
     /**
      * set configuration options of the traffic limiter
      *
@@ -62,6 +84,8 @@ class TrafficLimiter extends AbstractPersistence
     {
         self::setLimit($conf->getKey('limit', 'traffic'));
         self::setPath($conf->getKey('dir', 'traffic'));
+        self::setExemptedIp($conf->getKey('exemptedIp', 'traffic'));
+
         if (($option = $conf->getKey('header', 'traffic')) !== null) {
             $httpHeader = 'HTTP_' . $option;
             if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader])) {
@@ -100,6 +124,32 @@ class TrafficLimiter extends AbstractPersistence
             return true;
         }
 
+        // Check if $_ipKey is exempted from ratelimiting
+        if (!is_null(self::$_exemptedIp)) {
+            $exIp_array = explode(',', self::$_exemptedIp);
+            foreach ($exIp_array as $ipRange) {
+                // Match $_ipKey to $ipRange and if it matches it will return with a true
+                $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)
+                if ($range == null) {
+                    $contained = false;
+                } else {
+                    // Ip-lib does throws and exception when something goes wrong, if so we want to catch it and set contained to false
+                    try {
+                        $contained = $address->matches($range);
+                    } catch (\Exception $e) {
+                        // If something is wrong with matching the ip, we set $contained to false
+                        $contained = false;
+                    }
+                }
+                // Matches return true!
+                if ($contained == true) {
+                    return true;
+                }
+            }
+        }
+
         $file = 'traffic_limiter.php';
         if (self::_exists($file)) {
             require self::getPath($file);