Package: release.debian.org
User: release.debian....@packages.debian.org
Usertags: pu
Tags: buster
Severity: normal

Hi Adam, all,

[ Reason ]
A CVE was discovered in cacti and fixed upstream. I backported the patch
to the buster package. Related, other security issues were discovered
and fixed.

[ Impact ]
A SQL injection vulnerability in data_debug.php allows remote
authenticated attackers to execute arbitrary SQL commands via the
site_id parameter. This can lead to remote code execution. CVE-2020-35701.

Additionally, there are a few places in the current code where an
attacker, once having gained access to the Cacti database through a SQL
injection, could modify data in tables to possibly expose an stored XSS
bug in Cacti.

[ Tests ]
I have run the autopkgtest included in the source package.

[ Risks ]
The call to the input sanitizer is moved from within the default
alternative to the start of the code. Hence, the change is simple and
the actual code has always been in the default code path, so I think the
risk for the CVE fix is low.

The patch for the other issues didn't apply, so I had to adapt it to the
code base in buster. I've inspected both the final patch and the diff
between upstream's changes and the final patch, both look sane. The
changes are exclusively calling an existing used function to sanitize
input additionally or instead of a text trim command (which upstream
claims is not needed anymore). I think the risk is low.

[ Checklist ]
  [✓] *all* changes are documented in the d/changelog
  [✓] I reviewed all changes and I approve them
  [✓] attach debdiff against the package in stable
  [✓] the issue is verified as fixed in unstable

[ Changes ]
Upstream patches added to the patch set.

[ Other info ]
I've discussed with carnil if this warrants a DSA but we thought this
made sense to fix via a point release.

I have already uploaded the package.

Paul
diff -Nru cacti-1.2.2+ds1/debian/changelog cacti-1.2.2+ds1/debian/changelog
--- cacti-1.2.2+ds1/debian/changelog    2020-06-18 22:34:41.000000000 +0200
+++ cacti-1.2.2+ds1/debian/changelog    2021-01-21 20:16:38.000000000 +0100
@@ -1,3 +1,15 @@
+cacti (1.2.2+ds1-2+deb10u4) buster; urgency=medium
+
+  * Add 0001-Fixing-Issue-4022.patch (Closes: #979998)
+    - CVE-2020-35701: SQL injection via data_debug.php
+  * Add 0001-Fixing-Issue-4019.patch
+    There are a few places in the current code where an attacker, once
+    having gained access to the Cacti database through a SQL injection,
+    could modify data in tables to possibly expose an stored XSS bug in
+    Cacti.
+
+ -- Paul Gevers <elb...@debian.org>  Thu, 21 Jan 2021 20:16:38 +0100
+
 cacti (1.2.2+ds1-2+deb10u3) buster; urgency=medium
 
   * Unix timestamps after Sep 13 2020 are rejected as graph start/end
diff -Nru cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4019.patch 
cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4019.patch
--- cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4019.patch 1970-01-01 
01:00:00.000000000 +0100
+++ cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4019.patch 2021-01-21 
20:16:38.000000000 +0100
@@ -0,0 +1,222 @@
+From ef10fe1c340ed932dc18b6a566b21f9dd15933c2 Mon Sep 17 00:00:00 2001
+From: TheWitness <thewitn...@cacti.net>
+Date: Wed, 23 Dec 2020 16:33:27 -0500
+Subject: [PATCH] Fixing Issue #4019
+
+* In a recent audit of core Cacti code, there were a few stored XSS issues 
that can be exposed
+* Also removed a few spurious title_trims, that should no longer be a problem.
+---
+ CHANGELOG              |  1 +
+ automation_devices.php | 10 +++++-----
+ data_debug.php         |  6 +++---
+ data_sources.php       |  2 +-
+ lib/api_automation.php | 22 +++++++++++-----------
+ lib/html.php           |  9 +++++----
+ lib/html_graph.php     | 10 +++++-----
+ lib/html_tree.php      |  4 ++--
+ managers.php           |  2 +-
+ utilities.php          | 20 ++++++++++----------
+ 10 files changed, 44 insertions(+), 42 deletions(-)
+
+Index: cacti/automation_devices.php
+===================================================================
+--- cacti.orig/automation_devices.php
++++ cacti/automation_devices.php
+@@ -466,7 +466,7 @@ function draw_filter() {
+                                                       <?php
+                                                       if 
(cacti_sizeof($networks)) {
+                                                       foreach ($networks as 
$key => $name) {
+-                                                              print "<option 
value='" . $key . "'"; if (get_request_var('network') == $key) { print ' 
selected'; } print '>' . $name . "</option>\n";
++                                                              print "<option 
value='" . html_escape($key) . "'"; if (get_request_var('network') == $key) { 
print ' selected'; } print '>' . html_escape($name) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+@@ -496,7 +496,7 @@ function draw_filter() {
+                                                       <?php
+                                                       if 
(cacti_sizeof($status_arr)) {
+                                                       foreach ($status_arr as 
$st) {
+-                                                              print "<option 
value='" . $st . "'"; if (get_request_var('status') == $st) { print ' 
selected'; } print '>' . $st . "</option>\n";
++                                                              print "<option 
value='" . html_escape($st) . "'"; if (get_request_var('status') == $st) { 
print ' selected'; } print '>' . html_escape($st) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+@@ -511,7 +511,7 @@ function draw_filter() {
+                                                       <?php
+                                                       if 
(cacti_sizeof($os_arr)) {
+                                                       foreach ($os_arr as 
$st) {
+-                                                              print "<option 
value='" . $st . "'"; if (get_request_var('os') == $st) { print ' selected'; } 
print '>' . $st . "</option>\n";
++                                                              print "<option 
value='" . html_escape($st) . "'"; if (get_request_var('os') == $st) { print ' 
selected'; } print '>' . html_escape($st) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+@@ -526,7 +526,7 @@ function draw_filter() {
+                                                       <?php
+                                                       if 
(cacti_sizeof($status_arr)) {
+                                                       foreach ($status_arr as 
$st) {
+-                                                              print "<option 
value='" . $st . "'"; if (get_request_var('snmp') == $st) { print ' selected'; 
} print '>' . $st . "</option>\n";
++                                                              print "<option 
value='" . html_escape($st) . "'"; if (get_request_var('snmp') == $st) { print 
' selected'; } print '>' . html_escape($st) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+@@ -541,7 +541,7 @@ function draw_filter() {
+                                                       <?php
+                                                       if 
(cacti_sizeof($item_rows) > 0) {
+                                                       foreach ($item_rows as 
$key => $value) {
+-                                                              print "<option 
value='" . $key . "'"; if (get_request_var('rows') == $key) { print ' 
selected'; } print '>' . $value . "</option>\n";
++                                                              print "<option 
value='" . $key . "'"; if (get_request_var('rows') == $key) { print ' 
selected'; } print '>' . html_escape($value) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+Index: cacti/lib/api_automation.php
+===================================================================
+--- cacti.orig/lib/api_automation.php
++++ cacti/lib/api_automation.php
+@@ -155,7 +155,7 @@ function display_matching_hosts($rule, $
+ 
+                                                               if 
(cacti_sizeof($host_templates)) {
+                                                                       foreach 
($host_templates as $host_template) {
+-                                                                              
print "<option value='" . $host_template['id'] . "'"; if 
(get_request_var('host_template_id') == $host_template['id']) { print ' 
selected'; } print '>' . $host_template['name'] . "</option>\n";
++                                                                              
print "<option value='" . $host_template['id'] . "'"; if 
(get_request_var('host_template_id') == $host_template['id']) { print ' 
selected'; } print '>' . html_escape($host_template['name']) . "</option>\n";
+                                                                       }
+                                                               }
+                                                               ?>
+@@ -452,7 +452,7 @@ function display_matching_graphs($rule,
+ 
+                                                               if 
(cacti_sizeof($templates) > 0) {
+                                                                       foreach 
($templates as $template) {
+-                                                                              
print "<option value=' " . $template['id'] . "'"; if 
(get_request_var('template_id') == $template['id']) { print ' selected'; } 
print '>' . title_trim($template['name'], 40) . "</option>\n";
++                                                                              
print "<option value=' " . $template['id'] . "'"; if 
(get_request_var('template_id') == $template['id']) { print ' selected'; } 
print '>' . html_escape($template['name']) . "</option>\n";
+                                                                       }
+                                                               }
+                                                               ?>
+@@ -1074,7 +1074,7 @@ function display_matching_trees ($rule_i
+ 
+                                                       if 
(cacti_sizeof($host_templates) > 0) {
+                                                       foreach 
($host_templates as $host_template) {
+-                                                              print "<option 
value='" . $host_template['id'] . "'"; if (get_request_var('host_template_id') 
== $host_template['id']) { print ' selected'; } print '>' . 
$host_template['name'] . "</option>\n";
++                                                              print "<option 
value='" . $host_template['id'] . "'"; if (get_request_var('host_template_id') 
== $host_template['id']) { print ' selected'; } print '>' . 
html_escape($host_template['name']) . "</option>\n";
+                                                       }
+                                                       }
+                                                       ?>
+Index: cacti/lib/html.php
+===================================================================
+--- cacti.orig/lib/html.php
++++ cacti/lib/html.php
+@@ -954,7 +954,7 @@ function html_create_list($form_data, $c
+                                       print ' selected';
+                               }
+ 
+-                              print '>' . 
title_trim(null_out_substitutions(html_escape($form_data[$id])), 75) . 
"</option>\n";
++                              print '>' . 
html_escape(null_out_substitutions($form_data[$id])) . "</option>\n";
+                       }
+               }
+       } else {
+@@ -967,9 +967,9 @@ function html_create_list($form_data, $c
+                               }
+ 
+                               if (isset($row['host_id'])) {
+-                                      print '>' . 
title_trim(html_escape($row[$column_display]), 75) . "</option>\n";
++                                      print '>' . 
html_escape($row[$column_display]) . "</option>\n";
+                               } else {
+-                                      print '>' . 
title_trim(null_out_substitutions(html_escape($row[$column_display])), 75) . 
"</option>\n";
++                                      print '>' . 
html_escape(null_out_substitutions($row[$column_display])) . "</option>\n";
+                               }
+                       }
+               }
+Index: cacti/lib/html_graph.php
+===================================================================
+--- cacti.orig/lib/html_graph.php
++++ cacti/lib/html_graph.php
+@@ -260,7 +260,7 @@ function html_graph_preview_filter($page
+ 
+                                                       if 
(cacti_sizeof($graph_timespans)) {
+                                                               
foreach($graph_timespans as $value => $text) {
+-                                                                      print 
"<option value='$value'"; if ($_SESSION['sess_current_timespan'] == $value) { 
print ' selected'; } print '>' . $text . "</option>\n";
++                                                                      print 
"<option value='$value'"; if ($_SESSION['sess_current_timespan'] == $value) { 
print ' selected'; } print '>' . html_escape($text) . "</option>\n";
+                                                               }
+                                                       }
+                                                       ?>
+@@ -293,7 +293,7 @@ function html_graph_preview_filter($page
+                                                               $end_val = 
cacti_sizeof($graph_timeshifts)+1;
+                                                               if 
(cacti_sizeof($graph_timeshifts) > 0) {
+                                                                       for 
($shift_value=$start_val; $shift_value < $end_val; $shift_value++) {
+-                                                                              
print "<option value='$shift_value'"; if ($_SESSION['sess_current_timeshift'] 
== $shift_value) { print ' selected'; } print '>' . 
title_trim($graph_timeshifts[$shift_value], 40) . "</option>\n";
++                                                                              
print "<option value='$shift_value'"; if ($_SESSION['sess_current_timeshift'] 
== $shift_value) { print ' selected'; } print '>' . 
html_escape($graph_timeshifts[$shift_value]) . "</option>\n";
+                                                                       }
+                                                               }
+                                                               ?>
+Index: cacti/lib/html_tree.php
+===================================================================
+--- cacti.orig/lib/html_tree.php
++++ cacti/lib/html_tree.php
+@@ -1056,7 +1056,7 @@ function grow_right_pane_tree($tree_id,
+ 
+                                                       if 
(cacti_sizeof($graph_timespans)) {
+                                                               
foreach($graph_timespans as $value => $text) {
+-                                                                      print 
"<option value='$value'"; if ($_SESSION['sess_current_timespan'] == $value) { 
print ' selected'; } print '>' . $text . "</option>\n";
++                                                                      print 
"<option value='$value'"; if ($_SESSION['sess_current_timespan'] == $value) { 
print ' selected'; } print '>' . html_escape($text) . "</option>\n";
+                                                               }
+                                                       }
+                                                       ?>
+@@ -1089,7 +1089,7 @@ function grow_right_pane_tree($tree_id,
+                                                               $end_val = 
cacti_sizeof($graph_timeshifts)+1;
+                                                               if 
(cacti_sizeof($graph_timeshifts)) {
+                                                                       for 
($shift_value=$start_val; $shift_value < $end_val; $shift_value++) {
+-                                                                              
print "<option value='$shift_value'"; if ($_SESSION['sess_current_timeshift'] 
== $shift_value) { print ' selected'; } print '>' . 
title_trim($graph_timeshifts[$shift_value], 40) . "</option>\n";
++                                                                              
print "<option value='$shift_value'"; if ($_SESSION['sess_current_timeshift'] 
== $shift_value) { print ' selected'; } print '>' . 
html_escape($graph_timeshifts[$shift_value]) . "</option>\n";
+                                                                       }
+                                                               }
+                                                               ?>
+Index: cacti/managers.php
+===================================================================
+--- cacti.orig/managers.php
++++ cacti/managers.php
+@@ -484,7 +484,7 @@ function manager_notifications($id, $hea
+                                                               <?php
+                                                               if 
(cacti_sizeof($mibs)) {
+                                                                       foreach 
($mibs as $mib) {
+-                                                                              
print "<option value='" . $mib['mib'] . "'"; if (get_request_var('mib') == 
$mib['mib']) { print ' selected'; } print '>' . $mib['mib'] . '</option>';
++                                                                              
print "<option value='" . html_escape($mib['mib']) . "'"; if 
(get_request_var('mib') == $mib['mib']) { print ' selected'; } print '>' . 
html_escape($mib['mib']) . '</option>';
+                                                                       }
+                                                               }
+                                                               ?>
+Index: cacti/utilities.php
+===================================================================
+--- cacti.orig/utilities.php
++++ cacti/utilities.php
+@@ -678,7 +678,7 @@ function utilities_view_user_log() {
+ 
+                                                       if 
(cacti_sizeof($users)) {
+                                                               foreach ($users 
as $user) {
+-                                                                      print 
"<option value='" . $user['username'] . "'"; if (get_request_var('username') == 
$user['username']) { print ' selected'; } print '>' . $user['username'] . 
"</option>\n";
++                                                                      print 
"<option value='" . html_escape($user['username']) . "'"; if 
(get_request_var('username') == $user['username']) { print ' selected'; } print 
'>' . html_escape($user['username']) . "</option>\n";
+                                                               }
+                                                       }
+                                                       ?>
+@@ -1067,7 +1067,7 @@ function utilities_view_logfile() {
+                                                                               
continue;
+                                                                       }
+ 
+-                                                                      print 
"<option value='" . $logFile . "'";
++                                                                      print 
"<option value='" . html_escape($logFile) . "'";
+ 
+                                                                       if 
($selectedFile == $logFile) {
+                                                                               
print ' selected';
+@@ -2407,7 +2407,7 @@ function snmpagent_utilities_run_cache()
+                                                               <?php
+                                                               if 
(cacti_sizeof($mibs) > 0) {
+                                                                       foreach 
($mibs as $mib) {
+-                                                                              
print "<option value='" . $mib['mib'] . "'"; if (get_request_var('mib') == 
$mib['mib']) { print ' selected'; } print '>' . html_escape($mib['mib']) . 
"</option>\n";
++                                                                              
print "<option value='" . html_escape($mib['mib']) . "'"; if 
(get_request_var('mib') == $mib['mib']) { print ' selected'; } print '>' . 
html_escape($mib['mib']) . "</option>\n";
+                                                                       }
+                                                               }
+                                                               ?>
+@@ -2670,7 +2670,7 @@ function snmpagent_utilities_run_eventlo
+                                                               <option 
value='-1'<?php if (get_request_var('receiver') == '-1') {?> selected<?php 
}?>><?php print __('Any');?></option>
+                                                               <?php
+                                                               foreach 
($receivers as $receiver) {
+-                                                                      print 
"<option value='" . $receiver['manager_id'] . "'"; if 
(get_request_var('receiver') == $receiver['manager_id']) { print ' selected'; } 
print '>' . $receiver['hostname'] . "</option>\n";
++                                                                      print 
"<option value='" . $receiver['manager_id'] . "'"; if 
(get_request_var('receiver') == $receiver['manager_id']) { print ' selected'; } 
print '>' . html_escape($receiver['hostname']) . "</option>\n";
+                                                               }
+                                                               ?>
+                                                       </select>
diff -Nru cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4022.patch 
cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4022.patch
--- cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4022.patch 1970-01-01 
01:00:00.000000000 +0100
+++ cacti-1.2.2+ds1/debian/patches/0001-Fixing-Issue-4022.patch 2021-01-21 
20:16:38.000000000 +0100
@@ -0,0 +1,36 @@
+From 565e0604a53f4988dc5b544d01f4a631eaa80d82 Mon Sep 17 00:00:00 2001
+From: TheWitness <thewitn...@cacti.net>
+Date: Thu, 24 Dec 2020 10:39:50 -0500
+Subject: [PATCH] Fixing Issue #4022
+
+SQL Injection in data_debug.php
+---
+ CHANGELOG      | 3 ++-
+ data_debug.php | 4 ++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/data_debug.php b/data_debug.php
+index 1bbed6a0a..a7ffe0829 100644
+--- a/data_debug.php
++++ b/data_debug.php
+@@ -35,6 +35,8 @@ ini_set('memory_limit', '-1');
+ 
+ set_default_action();
+ 
++validate_request_vars();
++
+ switch (get_request_var('action')) {
+       case 'actions':
+               form_actions();
+@@ -123,8 +125,6 @@ switch (get_request_var('action')) {
+ 
+               break;
+       default:
+-              validate_request_vars();
+-
+               $refresh = array(
+                       'seconds' => get_request_var('refresh'),
+                       'page'    => 'data_debug.php?header=false',
+-- 
+2.29.2
+
diff -Nru cacti-1.2.2+ds1/debian/patches/series 
cacti-1.2.2+ds1/debian/patches/series
--- cacti-1.2.2+ds1/debian/patches/series       2020-06-18 22:34:41.000000000 
+0200
+++ cacti-1.2.2+ds1/debian/patches/series       2021-01-21 20:16:38.000000000 
+0100
@@ -16,3 +16,5 @@
 107bfecebfdd060a81b91f146471648ebb7284a0.patch
 25abe64483752f7585ae17b699167b0abe849833.patch
 ec0d1f8422405500d7f4792071e3b313df10bd19.patch
+0001-Fixing-Issue-4022.patch
+0001-Fixing-Issue-4019.patch

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to