summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2020-05-07 12:17:51 +0200
committerSimon Rettberg2020-05-07 12:17:51 +0200
commita1538dc3b2b83f8cf2370347ee25b055b1a97cfb (patch)
tree9d3c7de5c242f831c9d9a4c02a7eb06438e9c286
parent[statistics] Re-introduce "with sublocations" for location filter (diff)
downloadslx-admin-a1538dc3b2b83f8cf2370347ee25b055b1a97cfb.tar.gz
slx-admin-a1538dc3b2b83f8cf2370347ee25b055b1a97cfb.tar.xz
slx-admin-a1538dc3b2b83f8cf2370347ee25b055b1a97cfb.zip
[statistics] Stricter verification of IP addresses
-rw-r--r--modules-available/statistics/inc/statisticsfilter.inc.php34
1 files changed, 31 insertions, 3 deletions
diff --git a/modules-available/statistics/inc/statisticsfilter.inc.php b/modules-available/statistics/inc/statisticsfilter.inc.php
index a038f076..e741652f 100644
--- a/modules-available/statistics/inc/statisticsfilter.inc.php
+++ b/modules-available/statistics/inc/statisticsfilter.inc.php
@@ -530,16 +530,44 @@ class IpStatisticsFilter extends StatisticsFilter
parent::__construct('clientip', self::OP_NOMINAL, '1.2.3.4, 1.2.3.*, 1.2.3/24');
}
- public function whereClause(string $operator, $argument, array &$args, array &$joins)
+ public function whereClause(string $operator, $argument, array &$args, array &$joins) : string
{
- $argument = preg_replace('#[^0-9.:/*]#', '', $argument);
- if (strpos($argument, '/') !== false) {
+ $argument = strtolower(preg_replace('#[^0-9a-f.:/*]#i', '', $argument));
+ if (filter_var($argument, FILTER_VALIDATE_IP) !== false) {
+ // Valid \o/ - do nothing to $argument
+ } elseif (strpos($argument, '/') !== false) {
+ // TODO: IPv6 CIDR
$range = IpUtil::parseCidr($argument);
if ($range === false) {
Message::addError('invalid-cidr-notion', $argument);
return '0';
}
return 'INET_ATON(clientip) BETWEEN ' . $range['start'] . ' AND ' . $range['end'];
+ } elseif (($num = substr_count($argument, ':')) !== 0 && $num <= 7) {
+ // IPv6, not yet in DB but let's prepare
+ if ($num > 7 || strpos($argument, '::') !== false) { // Too many :, or invalid compressed format
+ Message::addError('invalid-ip-address', $argument);
+ return '0';
+ } elseif ($num <= 7 && substr($argument, -1) === ':') {
+ $argument .= '*';
+ } elseif ($num < 7) {
+ $argument .= ':*';
+ } else {
+ Message::addError('invalid-ip-address', $argument);
+ return '0';
+ }
+ } elseif (($num = substr_count($argument, '.')) !== 0 && $num <= 3) {
+ if (substr($argument, -1) === '.') {
+ $argument .= '*';
+ } elseif ($num < 3) {
+ $argument .= '.*';
+ } else {
+ Message::addError('invalid-ip-address', $argument);
+ return '0';
+ }
+ } else {
+ Message::addError('invalid-ip-address', $argument);
+ return '0';
}
return "clientip LIKE '" . str_replace('*', '%', $argument) . "'";
}