From a3b6d227baffe910d67628cf9d6ed343aec86125 Mon Sep 17 00:00:00 2001 From: Artem Pakhomov Date: Wed, 20 Mar 2019 13:44:22 +0200 Subject: [PATCH] Fixes #16335: Fixed in `yii\filters\AccessRule::matchIP()` user IP validation with netmask in rule --- framework/CHANGELOG.md | 1 + framework/filters/AccessRule.php | 5 ++++ tests/framework/filters/AccessRuleTest.php | 41 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index a975d6f..465a81d 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.17 under development ------------------------ +- Bug #16335: Fixed in `yii\filters\AccessRule::matchIP()` user IP validation with netmask in rule (omentes) - Bug #9438, #13740, #15037: Handle DB session callback custom fields before session closed (lubosdz) - Bug #16681: `ActiveField::inputOptions` were not used during some widgets rendering (GHopperMSK) - Bug #17133: Fixed aliases rendering during help generation for a console command (GHopperMSK) diff --git a/framework/filters/AccessRule.php b/framework/filters/AccessRule.php index a89ef59..a6966c2 100644 --- a/framework/filters/AccessRule.php +++ b/framework/filters/AccessRule.php @@ -12,6 +12,7 @@ use yii\base\Action; use yii\base\Component; use yii\base\Controller; use yii\base\InvalidConfigException; +use yii\helpers\IpHelper; use yii\helpers\StringHelper; use yii\web\Request; use yii\web\User; @@ -266,6 +267,10 @@ class AccessRule extends Component $ip !== null && ($pos = strpos($rule, '*')) !== false && strncmp($ip, $rule, $pos) === 0 + ) || + ( + ($pos = strpos($rule, '/')) !== false && + IpHelper::inRange($ip, $rule) === true ) ) { return true; diff --git a/tests/framework/filters/AccessRuleTest.php b/tests/framework/filters/AccessRuleTest.php index a455063..199faa3 100644 --- a/tests/framework/filters/AccessRuleTest.php +++ b/tests/framework/filters/AccessRuleTest.php @@ -524,4 +524,45 @@ class AccessRuleTest extends \yiiunit\TestCase $rule->allow = false; $this->assertNull($rule->allows($action, $user, $request)); } + + public function testMatchIPMask() + { + $action = $this->mockAction(); + $user = false; + $request = $this->mockRequest(); + + $rule = new AccessRule(); + + // no match + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + $rule->ips = ['127.0.0.32/27']; + $rule->allow = true; + $this->assertNull($rule->allows($action, $user, $request)); + $rule->allow = false; + $this->assertNull($rule->allows($action, $user, $request)); + + // match + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + $rule->ips = ['127.0.0.1/27']; + $rule->allow = true; + $this->assertTrue($rule->allows($action, $user, $request)); + $rule->allow = false; + $this->assertFalse($rule->allows($action, $user, $request)); + + // match, IPv6 + $_SERVER['REMOTE_ADDR'] = '2a01:4f8:120:7202::2'; + $rule->ips = ['2a01:4f8:120:7202::2/127']; + $rule->allow = true; + $this->assertTrue($rule->allows($action, $user, $request)); + $rule->allow = false; + $this->assertFalse($rule->allows($action, $user, $request)); + + // no match, IPv6 + $_SERVER['REMOTE_ADDR'] = '2a01:4f8:120:7202::ffff'; + $rule->ips = ['2a01:4f8:120:7202::2/123']; + $rule->allow = true; + $this->assertNull($rule->allows($action, $user, $request)); + $rule->allow = false; + $this->assertNull($rule->allows($action, $user, $request)); + } }