fix: [internal] CIDR validation

pull/8170/head
Jakub Onderka 2022-02-23 09:52:59 +01:00 committed by Jakub Onderka
parent 8424b2637f
commit b32f397949
3 changed files with 32 additions and 13 deletions

View File

@ -78,9 +78,15 @@ class CidrTool
return false; return false;
} }
$maximumNetmask = strlen($ipBytes) === 4 ? 32 : 128; if (isset($parts[1])) {
if (isset($parts[1]) && ($parts[1] > $maximumNetmask || $parts[1] < 0)) { if (!ctype_digit($parts[1])) {
return false; // Netmask part of CIDR is invalid return false;
}
$maximumNetmask = strlen($ipBytes) === 4 ? 32 : 128;
if ($parts[1] > $maximumNetmask || $parts[1] < 0) {
return false; // Netmask part of CIDR is invalid
}
} }
return true; return true;

View File

@ -2,6 +2,7 @@
App::uses('AppModel', 'Model'); App::uses('AppModel', 'Model');
App::uses('RandomTool', 'Tools'); App::uses('RandomTool', 'Tools');
App::uses('CidrTool', 'Tools'); App::uses('CidrTool', 'Tools');
App::uses('JsonTool', 'Tools');
App::uses('BlowfishConstantPasswordHasher', 'Controller/Component/Auth'); App::uses('BlowfishConstantPasswordHasher', 'Controller/Component/Auth');
/** /**
@ -47,19 +48,20 @@ class AuthKey extends AppModel
} }
if (!empty($this->data['AuthKey']['allowed_ips'])) { if (!empty($this->data['AuthKey']['allowed_ips'])) {
if (is_string($this->data['AuthKey']['allowed_ips'])) { $allowedIps = &$this->data['AuthKey']['allowed_ips'];
$this->data['AuthKey']['allowed_ips'] = trim($this->data['AuthKey']['allowed_ips']); if (is_string($allowedIps)) {
if (empty($this->data['AuthKey']['allowed_ips'])) { $allowedIps = trim($allowedIps);
$this->data['AuthKey']['allowed_ips'] = []; if (empty($allowedIps)) {
$allowedIps = [];
} else { } else {
$this->data['AuthKey']['allowed_ips'] = explode("\n", $this->data['AuthKey']['allowed_ips']); $allowedIps = preg_split('/([\n,])/', $allowedIps);
$this->data['AuthKey']['allowed_ips'] = array_map('trim', $this->data['AuthKey']['allowed_ips']); $allowedIps = array_map('trim', $allowedIps);
} }
} }
if (!is_array($this->data['AuthKey']['allowed_ips'])) { if (!is_array($allowedIps)) {
$this->invalidate('allowed_ips', 'Allowed IPs must be array'); $this->invalidate('allowed_ips', 'Allowed IPs must be array');
} }
foreach ($this->data['AuthKey']['allowed_ips'] as $cidr) { foreach ($allowedIps as $cidr) {
if (!CidrTool::validate($cidr)) { if (!CidrTool::validate($cidr)) {
$this->invalidate('allowed_ips', "$cidr is not valid IP range"); $this->invalidate('allowed_ips', "$cidr is not valid IP range");
} }
@ -91,7 +93,7 @@ class AuthKey extends AppModel
{ {
foreach ($results as $key => $val) { foreach ($results as $key => $val) {
if (isset($val['AuthKey']['allowed_ips'])) { if (isset($val['AuthKey']['allowed_ips'])) {
$results[$key]['AuthKey']['allowed_ips'] = $this->jsonDecode($val['AuthKey']['allowed_ips']); $results[$key]['AuthKey']['allowed_ips'] = JsonTool::decode($val['AuthKey']['allowed_ips']);
} }
} }
return $results; return $results;
@ -103,7 +105,7 @@ class AuthKey extends AppModel
if (empty($this->data['AuthKey']['allowed_ips'])) { if (empty($this->data['AuthKey']['allowed_ips'])) {
$this->data['AuthKey']['allowed_ips'] = null; $this->data['AuthKey']['allowed_ips'] = null;
} else { } else {
$this->data['AuthKey']['allowed_ips'] = json_encode($this->data['AuthKey']['allowed_ips']); $this->data['AuthKey']['allowed_ips'] = JsonTool::encode($this->data['AuthKey']['allowed_ips']);
} }
} }
return true; return true;

View File

@ -5,6 +5,17 @@ use PHPUnit\Framework\TestCase;
class CidrToolTest extends TestCase class CidrToolTest extends TestCase
{ {
public function testValidate(): void
{
$this->assertTrue(CidrTool::validate('1.2.3.4'));
$this->assertTrue(CidrTool::validate('1.2.3.4/32'));
$this->assertTrue(CidrTool::validate('::1'));
$this->assertTrue(CidrTool::validate('::1/128'));
$this->assertFalse(CidrTool::validate('::1/a'));
$this->assertFalse(CidrTool::validate('1.2.3.4/a'));
$this->assertFalse(CidrTool::validate('1.2.3.4/32, 1.2.3.4'));
}
public function testEmptyList(): void public function testEmptyList(): void
{ {
$cidrTool = new CidrTool([]); $cidrTool = new CidrTool([]);