From 4514ceddd553643607cd02ff45022e8f70112073 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 10 Aug 2022 08:55:06 -0400 Subject: [PATCH] Rework code to be smaller. Don't require SystemView permission to post a log entry. Default to ERR if invalid err code provided instead of PANIC so that the log entry still gets saved --- web/ajax/log.php | 84 ++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/web/ajax/log.php b/web/ajax/log.php index 513c9f63f..0d371d52c 100644 --- a/web/ajax/log.php +++ b/web/ajax/log.php @@ -6,39 +6,33 @@ $message = ''; // INITIALIZE AND CHECK SANITY // -if ( !canView('System') ) - $message = 'Insufficient permissions to view log entries for user '.$user['Username']; // task must be set -if ( !isset($_REQUEST['task']) ) { +if (!isset($_REQUEST['task'])) { $message = 'This request requires a task to be set'; -} else if ( $_REQUEST['task'] != 'query' && $_REQUEST['task'] != 'create' ) { +} else if ($_REQUEST['task'] == 'query') { + if (!canView('System')) { + $message = 'Insufficient permissions to view log entries for user '.$user['Username']; + } else { + $data = queryRequest(); + } +} else if ($_REQUEST['task'] == 'create' ) { + global $user; + if (!$user) { + // We allow any logged in user to create logs. This opens us up to DOS by malicious user + $message = 'Insufficient permissions to view log entries for user '.$user['Username']; + } else { + createRequest(); + } +} else { // Only the query and create tasks are supported at the moment $message = 'Unrecognised task '.$_REQUEST['task']; -} else { - $task = $_REQUEST['task']; } -if ( $message ) { +if ($message) { ajaxError($message); return; } - -// -// MAIN LOOP -// - -switch ( $task ) { - case 'create' : - createRequest(); - break; - case 'query' : - $data = queryRequest(); - break; - default : - ZM\Fatal('Unrecognised task '.$task); -} // end switch task - ajaxResponse($data); // @@ -46,35 +40,29 @@ ajaxResponse($data); // function createRequest() { - if ( !empty($_POST['level']) && !empty($_POST['message']) ) { + if (!empty($_POST['level']) && !empty($_POST['message'])) { ZM\logInit(array('id'=>'web_js')); - $string = $_POST['message']; - $file = !empty($_POST['file']) ? preg_replace('/\w+:\/\/[\w.:]+\//', '', $_POST['file']) : ''; - if ( !empty($_POST['line']) ) { - $line = validInt($_POST['line']); - } else { - $line = NULL; - } + $line = empty($_POST['line']) ? NULL : validInt($_POST['line']); $levels = array_flip(ZM\Logger::$codes); - if ( !isset($levels[$_POST['level']]) ) { - ZM\Panic('Unexpected logger level '.$_POST['level']); + if (!isset($levels[$_POST['level']])) { + ZM\Error('Unexpected logger level '.$_POST['level']); + $_POST['level'] = 'ERR'; } $level = $levels[$_POST['level']]; - ZM\Logger::fetch()->logPrint($level, $string, $file, $line); + ZM\Logger::fetch()->logPrint($level, $_POST['message'], $file, $line); } else { ZM\Error('Invalid log create: '.print_r($_POST, true)); } } function queryRequest() { - // Offset specifies the starting row to return, used for pagination $offset = 0; - if ( isset($_REQUEST['offset']) ) { - if ( ( !is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']) ) ) { + if (isset($_REQUEST['offset'])) { + if ((!is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']))) { ZM\Error('Invalid value for offset: ' . $_REQUEST['offset']); } else { $offset = $_REQUEST['offset']; @@ -83,8 +71,8 @@ function queryRequest() { // Limit specifies the number of rows to return $limit = 100; - if ( isset($_REQUEST['limit']) ) { - if ( ( !is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']) ) ) { + if (isset($_REQUEST['limit'])) { + if ((!is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']))) { ZM\Error('Invalid value for limit: ' . $_REQUEST['limit']); } else { $limit = $_REQUEST['limit']; @@ -100,11 +88,11 @@ function queryRequest() { $col_alt = array('DateTime', 'Server'); $sort = 'TimeKey'; - if ( isset($_REQUEST['sort']) ) { + if (isset($_REQUEST['sort'])) { $sort = $_REQUEST['sort']; - if ( $sort == 'DateTime' ) $sort = 'TimeKey'; + if ($sort == 'DateTime') $sort = 'TimeKey'; } - if ( !in_array($sort, array_merge($columns, $col_alt)) ) { + if (!in_array($sort, array_merge($columns, $col_alt))) { ZM\Error('Invalid sort field: ' . $sort); return; } @@ -127,10 +115,9 @@ function queryRequest() { $advsearch = isset($_REQUEST['filter']) ? json_decode($_REQUEST['filter'], JSON_OBJECT_AS_ARRAY) : array(); // Search contains a user entered string to search on $search = isset($_REQUEST['search']) ? $_REQUEST['search'] : ''; - if ( count($advsearch) ) { - - foreach ( $advsearch as $col=>$text ) { - if ( !in_array($col, array_merge($columns, $col_alt)) ) { + if (count($advsearch)) { + foreach ($advsearch as $col=>$text) { + if (!in_array($col, array_merge($columns, $col_alt))) { ZM\Error("'$col' is not a searchable column name"); continue; } @@ -142,8 +129,7 @@ function queryRequest() { $wherevalues = $query['values']; $where = ' WHERE (' .implode(' OR ', $likes). ')'; - } else if ( $search != '' ) { - + } else if ($search != '') { $search = '%' .$search. '%'; foreach ( $columns as $col ) { array_push($likes, $col.' LIKE ?'); @@ -167,7 +153,7 @@ function queryRequest() { $results = dbFetchAll($query['sql'], NULL, $query['values']); global $dateTimeFormatter; - foreach ( $results as $row ) { + foreach ($results as $row) { $row['DateTime'] = $dateTimeFormatter->format($row['TimeKey']); $Server = ZM\Server::find_one(array('Id'=>$row['ServerId']));