Skip to content

Commit 0058fef

Browse files
committed
QA: Merging Security Updates from 1.2.x into develop
1 parent 8ccb723 commit 0058fef

9 files changed

+90
-23
lines changed

CHANGELOG

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Cacti CHANGELOG
121121
-feature#5328: Search through Data Query fields when searching for Graphs in Tree
122122
-feature#5368: Allow all key searching calls to be delayed by defined amount
123123
-feature#5378: When reload page in browser with graphs created scroll window always return to top
124-
-feature#5389: Forgot password function and email notification about new user or reset user password
124+
-feature#5389: Forgot password function and email notification about new user or reset user password
125125
-feature#5406: Cacti connection handling should forcibly close connections to work around PDO uncertainty
126126
-feature#5407: Add last_updated column to the boost table to increase diagnostics in Cacti
127127
-feature#5416: Display device class before package import
@@ -169,12 +169,12 @@ Cacti CHANGELOG
169169
-feature#5970: Import/Export Automation should take THold into account
170170
-feature#5971: Add a method to mark missing Data in all graphs globally
171171
-feature#5993: Allow Automation Rules to Search through Site Information
172-
-feature#5997: Add filter for devices in maintenance plan, add icon to device list
172+
-feature#5997: Add filter for devices in maintenance plan, add icon to device list
173173
-feature#6001: Extend SYSTEM STATS log entry
174174
-feature#6033: Allow Admins to see when a template was last modified
175175
-feature#6034: Allow Users to Drill Up from CDEF's and VDEF's to Graphs and Graph Templates
176176
-feature#6044: Enable the capabilities to view historical Classical Cacti Report from the GUI
177-
-feature#6063: Change installer page Input Validation Whitelist Protection to Recommendations
177+
-feature#6063: Change installer page Input Validation Whitelist Protection to Recommendations
178178
-feature#6066: Enable Drag and Drop for External Links
179179
-feature: Allow messages to be popup notifications
180180
-feature: Upgrade billboard.js to version 3.14.1
@@ -190,6 +190,12 @@ Cacti CHANGELOG
190190
-feature: Remove legacy Lotus Notes Attachment Types from Reports
191191

192192
1.2.29
193+
-security#GHSA-pv2c-97pp-vxwg: Local File Inclusion (LFI) Vulnerability via Poller Standard Error Log Path
194+
-security#GHSA-f9c7-7rc3-574c: SQL Injection vulnerability when using tree rules through Automation API
195+
-security#GHSA-vj9g-P7F2-4wqj: SQL Injection vulnerability when view host template
196+
-security#GHSA-fh3x-69rr-qqpp: SQL Injection vulnerability when request automation devices
197+
-security#GHSA-c5j8-jxj3-hh36: Authenticated RCE via multi-line SNMP responses
198+
-security#GHSA-fxrq-fr7h-9rqq: Arbitrary File Creation leading to RCE
193199
-issue#5843: Issue with temporary tables with use of microtime
194200
-issue#5847: Presets Time in Cacti 1.2.28 Not Automatically Updating...
195201
-issue#5848: RRDfile Auto Clean not working
@@ -204,7 +210,7 @@ Cacti CHANGELOG
204210
-issue#5961: Issues with Replication of Tables and Misleading Full Sync Time
205211
-issue#5963: Cacti caching for db_table_exists() and db_column_exists() is not connection aware and replication does not replicate empty table structures
206212
-issue#5986: PHP ERRORS with php8.4 while including global_arrays.php
207-
-issue#5987: Please add a new line to upgrade_database script
213+
-issue#5987: Please add a new line to upgrade_database script
208214
-feature#5921: Add HPE Nimble/Alletra template
209215
-feature#5933: Only attempt to change the table type and character encoding for built-in Cacti tables
210216

automation_devices.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,14 +474,14 @@ function get_discovery_results(&$total_rows = 0, $rows = 0, $export = false) {
474474
$sql_params[] = $snmp;
475475
}
476476

477-
if ($os != '-1') {
478-
$sql_where .= ($sql_where != '' ? ' AND ':'WHERE ') . 'os= ?';
477+
if ($os != '-1' && in_array($os, $os_arr)) {
478+
$sql_where .= ($sql_where != '' ? ' AND ':'WHERE ') . 'os = ?';
479479
$sql_params[] = $network;
480480
}
481481

482482
if ($filter != '') {
483483
$sql_where .= ($sql_where != '' ? ' AND ':'WHERE ') .
484-
'(hostname LIKE ? OR ip LIKE ? OR sysName LIKE ? OR sysDescr ? OR sysLocation ? OR sysContact LIKE ?)';
484+
'(hostname LIKE ? OR ip LIKE ? OR sysName LIKE ? OR sysDescr LIKE ? OR sysLocation LIKE ? OR sysContact LIKE ?)';
485485

486486
$sql_params[] = "%$filter%";
487487
$sql_params[] = "%$filter%";
@@ -563,7 +563,7 @@ function create_filter() {
563563
'os' => array(
564564
'method' => 'drop_array',
565565
'friendly_name' => __('OS'),
566-
'filter' => FILTER_VALIDATE_INT,
566+
'filter' => FILTER_DEFAULT,
567567
'default' => '-1',
568568
'pageset' => true,
569569
'array' => $os_arr,

automation_graph_rules.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,19 @@ function form_save() {
293293
$save['operator'] = form_input_validate((isset_request_var('operator') ? get_nfilter_request_var('operator') : ''), 'operator', '^[0-9]+$', true, 3);
294294
$save['pattern'] = form_input_validate((isset_request_var('pattern') ? get_nfilter_request_var('pattern') : ''), 'pattern', '', true, 3);
295295

296+
/* Test for SQL injections */
297+
$field_name = str_replace(array('ht.', 'h.', 'gt.'), '', $save['field']);
298+
299+
if (!db_column_exists('host', $field_name) && !db_column_exists('host_template', $field_name) && !db_column_exists('graph_templates', $field_name)) {
300+
raise_messsage('sql_injection', __('An attempt was made to perform a SQL injection in Tree automation'), MESSAGE_LEVEL_ERROR);
301+
302+
cacti_log(sprintf('ERROR: An attempt was made to perform a SQL Injection in Graph Automation from client address \'%s\'', get_client_addr()), false, 'SECURITY');
303+
304+
header('Location: automation_graph_rules.php?header=false&action=edit&id=' . get_request_var('id') . '&rule_type=' . AUTOMATION_RULE_TYPE_GRAPH_ACTION);
305+
306+
exit;
307+
}
308+
296309
if (!is_error_message()) {
297310
$item_id = sql_save($save, 'automation_graph_rule_items');
298311

automation_tree_rules.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ function form_save() {
310310
$save['operator'] = form_input_validate((isset_request_var('operator') ? get_nfilter_request_var('operator') : ''), 'operator', '^[0-9]+$', true, 3);
311311
$save['pattern'] = form_input_validate((isset_request_var('pattern') ? get_nfilter_request_var('pattern') : ''), 'pattern', '', true, 3);
312312

313+
/* Test for SQL injections */
314+
$field_name = str_replace(array('ht.', 'h.', 'gt.'), '', $save['field']);
315+
316+
if (!db_column_exists('host', $field_name) && !db_column_exists('host_template', $field_name) && !db_column_exists('graph_templates', $field_name)) {
317+
raise_messsage('sql_injection', __('An attempt was made to perform a SQL injection in Tree automation'), MESSAGE_LEVEL_ERROR);
318+
319+
cacti_log(sprintf('ERROR: An attempt was made to perform a SQL Injection in Tree automation from client address \'%s\'', get_client_addr()), false, 'SECURITY');
320+
321+
header('Location: automation_tree_rules.php?header=false&action=item_edit&id=' . get_request_var('id') . '&item_id=' . (empty($item_id) ? get_request_var('item_id') : $item_id) . '&rule_type=' . AUTOMATION_RULE_TYPE_TREE_MATCH);
322+
323+
exit;
324+
}
325+
313326
if (!is_error_message()) {
314327
$item_id = sql_save($save, 'automation_match_rule_items');
315328

lib/functions.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5083,9 +5083,14 @@ function cacti_escapeshellarg(string $string, bool $quote = true): string {
50835083
return $string;
50845084
}
50855085

5086-
/* we must use an apostrophe to escape community names under Unix in case the user uses
5087-
characters that the shell might interpret. the ucd-snmp binaries on Windows flip out when
5088-
you do this, but are perfectly happy with a quotation mark. */
5086+
/* remove any carriage returns or line feeds from the argument */
5087+
$string = str_replace(array("\n", "\r"), array('', ''), $string);
5088+
5089+
/*
5090+
* we must use an apostrophe to escape community names under Unix in case the user uses
5091+
* characters that the shell might interpret. the ucd-snmp binaries on Windows flip out when
5092+
* you do this, but are perfectly happy with a quotation mark.
5093+
*/
50895094
if ($config['cacti_server_os'] == 'unix') {
50905095
$string = escapeshellarg($string);
50915096

@@ -5096,12 +5101,14 @@ function cacti_escapeshellarg(string $string, bool $quote = true): string {
50965101
return substr($string, 1, (strlen($string) - 2));
50975102
}
50985103
} else {
5099-
/* escapeshellarg takes care of different quotation for both linux and windows,
5104+
/**
5105+
* escapeshellarg takes care of different quotation for both linux and windows,
51005106
* but unfortunately, it blanks out percent signs
51015107
* we want to keep them, e.g. for GPRINT format strings
51025108
* so we need to create our own escapeshellarg
51035109
* on windows, command injection requires to close any open quotation first
5104-
* so we have to escape any quotation here */
5110+
* so we have to escape any quotation here
5111+
*/
51055112
if (substr_count($string, CACTI_ESCAPE_CHARACTER)) {
51065113
$string = str_replace(CACTI_ESCAPE_CHARACTER, '\\' . CACTI_ESCAPE_CHARACTER, $string);
51075114
}

lib/html_validate.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function html_log_input_error($variable) {
8484
* @param string|null $variable The name of the variable that caused the validation error.
8585
* @param string|null $value The value of the variable that caused the validation error.
8686
* @param string $message An optional custom error message.
87-
*
87+
*
8888
* @return void
8989
*/
9090
function die_html_input_error($variable = null, $value = null, $message = '') {

lib/snmp.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ function cacti_snmp_session_walk($session, $oid, $dummy = false, $max_repetition
489489
}
490490

491491
if (cacti_sizeof($out)) {
492-
foreach($out as $oid => $value){
492+
foreach($out as $oid => $value) {
493493
if (is_array($value)) {
494494
foreach($value as $index => $sval) {
495495
$out[$oid][$index] = format_snmp_string($sval, false, $value_output_format);
@@ -593,6 +593,18 @@ function cacti_snmp_session_getnext($session, $oid) {
593593
return $out;
594594
}
595595

596+
function cacti_snmp_validate_oid($oid) {
597+
$oid = ltrim($oid, '.');
598+
599+
$validate = array_unique(array_map('is_numeric', explode('.', $oid)));
600+
601+
if (array_search(false, $validate, true)) {
602+
return false;
603+
} else {
604+
return true;
605+
}
606+
}
607+
596608
function cacti_snmp_walk($hostname, $community, $oid, $version, $auth_user = '', $auth_pass = '',
597609
$auth_proto = '', $priv_pass = '', $priv_proto = '', $context = '',
598610
$port = 161, $timeout_ms = 500, $retries = 0, $bulk_walk_size = 10, $environ = 'SNMP',
@@ -737,9 +749,17 @@ function cacti_snmp_walk($hostname, $community, $oid, $version, $auth_user = '',
737749

738750
foreach ($temp_array as $index => $value) {
739751
if (preg_match('/(.*) =.*/', $value)) {
740-
$parts = explode('=', $value, 2);
741-
$snmp_array[$i]['oid'] = trim($parts[0]);
742-
$snmp_array[$i]['value'] = format_snmp_string($parts[1], false, $value_output_format);
752+
$parts = explode('=', $value, 2);
753+
$t_oid = trim($parts[0]);
754+
$t_value = $parts[1];
755+
756+
if (!cacti_snmp_validate_oid($t_oid)) {
757+
cacti_log(sprintf('WARNING: SNMP Agent exploit attempted on SNMP agent from host ip: %s with oid: %s', $hostname, $t_oid), false, 'SECURITY');
758+
continue;
759+
}
760+
761+
$snmp_array[$i]['oid'] = $t_oid;
762+
$snmp_array[$i]['value'] = $t_value;
743763
$i++;
744764
} else {
745765
$snmp_array[$i - 1]['value'] .= $value;
@@ -748,6 +768,15 @@ function cacti_snmp_walk($hostname, $community, $oid, $version, $auth_user = '',
748768
}
749769
}
750770

771+
/**
772+
* replay the array to escape value data in case of a multi-line exploit
773+
*/
774+
if (cacti_sizeof($snmp_array)) {
775+
foreach($snmp_array as $index => $data) {
776+
$snmp_array[$index]['value'] = format_snmp_string($data['value'], false, $value_output_format);
777+
}
778+
}
779+
751780
return $snmp_array;
752781
}
753782

scripts/ss_net_snmp_disk_bytes.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ function ss_net_snmp_disk_bytes($host_id_or_hostname = '') {
260260
}
261261

262262
if (!db_table_exists('host_value_cache')) {
263-
$data = "'" . json_encode($current) . "'";
264-
shell_exec("echo $data > $tmpdir/$tmpfile");
263+
$data = json_encode($current);
264+
file_put_contents("$tmpdir/$tmpfile", $data);
265265
} else {
266266
$data = json_encode($current);
267267

scripts/ss_net_snmp_disk_io.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,8 @@ function ss_net_snmp_disk_io($host_id_or_hostname = '') {
263263

264264

265265
if (!db_table_exists('host_value_cache')) {
266-
$data = "'" . json_encode($current) . "'";
267-
268-
shell_exec("echo $data > $tmpdir/$tmpfile");
266+
$data = json_encode($current);
267+
file_put_contents("$tmpdir/$tmpfile", $data);
269268
} else {
270269
$data = json_encode($current);
271270

0 commit comments

Comments
 (0)