diff options
author | Simon Rettberg | 2020-07-30 17:21:29 +0200 |
---|---|---|
committer | Simon Rettberg | 2020-07-30 17:21:29 +0200 |
commit | 71fe655d73db79fa03e17e8e414568c8ea0f5842 (patch) | |
tree | 13398be8bbdc9942461419c32eda5fda1b397c95 | |
parent | [exams] More sanity checks regarding date/time and locations (diff) | |
download | slx-admin-71fe655d73db79fa03e17e8e414568c8ea0f5842.tar.gz slx-admin-71fe655d73db79fa03e17e8e414568c8ea0f5842.tar.xz slx-admin-71fe655d73db79fa03e17e8e414568c8ea0f5842.zip |
[serversetup-bwlp-ipxe/statistics] Sanitize strings from clients
Some string from the clients might not be well suited for utf-8
representation. Add wrapper functions that clean utf-8 strings, or
convert ANSI strings to UTF-8 while removing problematic chars.
-rw-r--r-- | inc/util.inc.php | 33 | ||||
-rw-r--r-- | modules-available/serversetup-bwlp-ipxe/api.inc.php | 1 | ||||
-rw-r--r-- | modules-available/statistics/api.inc.php | 22 |
3 files changed, 47 insertions, 9 deletions
diff --git a/inc/util.inc.php b/inc/util.inc.php index 6be06bf6..83b2d54a 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -559,4 +559,37 @@ SADFACE; } } + /** + * Remove any non-utf8 sequences from string. + */ + public static function cleanUtf8(string $string) : string + { + // https://stackoverflow.com/a/1401716/2043481 + $regex = '/ + ( + (?: [\x00-\x7F] # single-byte sequences 0xxxxxxx + | [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx + | [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2 + | [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3 + ){1,100} # ...one or more times + ) + | . # anything else + /x'; + return preg_replace($regex, '$1', $string); + } + + /** + * Remove non-printable < 0x20 chars from ANSI string, then convert to UTF-8 + */ + public static function ansiToUtf8(string $string) : string + { + $regex = '/ + ( + (?: [\x20-\xFF] ){1,100} # ignore lower non-printable range + ) + | . # anything else + /x'; + return iconv('MS-ANSI', 'UTF-8', preg_replace($regex, '$1', $string)); + } + } diff --git a/modules-available/serversetup-bwlp-ipxe/api.inc.php b/modules-available/serversetup-bwlp-ipxe/api.inc.php index c3804a03..7dc03e11 100644 --- a/modules-available/serversetup-bwlp-ipxe/api.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/api.inc.php @@ -113,6 +113,7 @@ if ($model === false) { $model .= " ($manuf)"; } } + $model = Util::ansiToUtf8($model); // Some SMBIOSes contain corrupt/bogus strings } // Query if ($model !== false) { diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php index 30e0ebc8..3e7af1fc 100644 --- a/modules-available/statistics/api.inc.php +++ b/modules-available/statistics/api.inc.php @@ -51,8 +51,8 @@ if ($type{0} === '~') { $kvmstate = Request::post('kvmstate', 'UNKNOWN', 'string'); $valid = array('UNKNOWN', 'UNSUPPORTED', 'DISABLED', 'ENABLED'); if (!in_array($kvmstate, $valid)) $kvmstate = 'UNKNOWN'; - $cpumodel = Request::post('cpumodel', '', 'string'); - $systemmodel = Request::post('systemmodel', '', 'string'); + $cpumodel = Util::cleanUtf8(Request::post('cpumodel', '', 'string')); + $systemmodel = Util::cleanUtf8(Request::post('systemmodel', '', 'string')); $id44mb = Request::post('id44mb', 0, 'integer'); if ($id44mb < 0 || $id44mb > 10240000) $id44mb = 0; $badsectors = Request::post('badsectors', 0, 'integer'); @@ -61,7 +61,7 @@ if ($type{0} === '~') { if (!is_string($hostname) || $hostname === $ip) { $hostname = ''; } - $data = Request::post('data', '', 'string'); + $data = Util::cleanUtf8(Request::post('data', '', 'string')); // Prepare insert/update to machine table $new = array( 'uuid' => $uuid, @@ -99,7 +99,7 @@ if ($type{0} === '~') { $moresql .= ' hostname = :hostname,'; } if (($runmode = Request::post('runmode', false, 'string')) !== false) { - $new['currentrunmode'] = $runmode; + $new['currentrunmode'] = Util::cleanUtf8($runmode); $moresql .= ' currentrunmode = :currentrunmode,'; } $new['oldstate'] = $old['state']; @@ -224,7 +224,7 @@ if ($type{0} === '~') { $params['_' . $item] = ceil(Request::post($item, 0, 'int') / 1024); } if (($runmode = Request::post('runmode', false, 'string')) !== false) { - $params['currentrunmode'] = $runmode; + $params['currentrunmode'] = Util::cleanUtf8($runmode); $strUpdateBoottime .= ' currentrunmode = :currentrunmode, '; } // Figure out what's happening - state changes @@ -243,6 +243,9 @@ if ($type{0} === '~') { if ($sessionLength !== 0 || $old['logintime'] === 0) { // This event is a start of a new session, rather than an update $params['user'] = Request::post('user', null, 'string'); + if (is_string($params['user'])) { + $params['user'] = Util::cleanUtf8($params['user']); + } $res = Database::exec('UPDATE machine SET lastseen = UNIX_TIMESTAMP(),' . $strUpdateBoottime . " logintime = UNIX_TIMESTAMP(), currentuser = :user, currentsession = NULL, state = 'OCCUPIED' " @@ -290,7 +293,8 @@ if ($type{0} === '~') { if (!array_key_exists('name', $screen)) continue; // Filter bogus data - $screen['name'] = iconv('UTF-8', 'UTF-8//IGNORE', $screen['name']); + $screen['name'] = Util::cleanUtf8($screen['name']); + $port = Util::cleanUtf8($port); if (empty($screen['name'])) continue; if (array_key_exists($screen['name'], $hwids)) { @@ -321,7 +325,7 @@ if ($type{0} === '~') { . " VALUES (:id, :key, :value) ON DUPLICATE KEY UPDATE value = VALUES(value)", array( 'id' => $machinehwid, 'key' => $key, - 'value' => $value, + 'value' => Util::cleanUtf8($value), )); } } @@ -439,8 +443,8 @@ if ($type{0} === '.') { if ($type === '.vmchooser-session') { $user = Request::post('user', 'unknown', 'string'); $loguser = Request::post('loguser', 0, 'int') !== 0; - $sessionName = Request::post('name', 'unknown', 'string'); - $sessionUuid = Request::post('uuid', '', 'string'); + $sessionName = Util::cleanUtf8(Request::post('name', 'unknown', 'string')); + $sessionUuid = Util::cleanUtf8(Request::post('uuid', '', 'string')); $session = strlen($sessionUuid) === 36 ? $sessionUuid : $sessionName; Database::exec("UPDATE machine SET currentuser = :user, currentsession = :session WHERE clientip = :ip", compact('user', 'session', 'ip')); |