From 81ac1ab8115fa2fd098d4b55e948551b9a4d6118 Mon Sep 17 00:00:00 2001 From: TheWitness Date: Wed, 7 Oct 2026 15:20:58 -0400 Subject: [PATCH 1/3] security: move filter inline onChange/onClick handlers into ready() for CSP The threshold, notification list, notification queue, template and device/log status filter forms still carried inline onChange/onClick attributes on their selects and Clear/Go/Import/Export controls. Under Cacti's Content-Security-Policy these trip the script-src-attr directive (inline event handlers). Bind them in each view's existing $(function(){...}) ready block instead. Scope: thold.php, notify_queue.php, thold_templates.php, notify_lists.php, thold_graph.php (all gate-allowlisted UI files; no measured source changed). The cactiReturnTo() cancel buttons on the bulk-action confirmation pages are left as-is (shared Cacti-core pattern). Regenerated locales/po/cacti.pot for the shifted source line references. --- CHANGELOG.md | 1 + locales/po/cacti.pot | 2 +- notify_lists.php | 66 ++++++++++++++++++++++++++++++++------------ notify_queue.php | 10 +++++-- thold.php | 20 ++++++++++---- thold_graph.php | 64 ++++++++++++++++++++++++++++++------------ thold_templates.php | 36 ++++++++++++++++++++---- 7 files changed, 148 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf316b9c..c28852ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## ChangeLog --- develop --- +* security: Move the filter controls' inline `onChange`/`onClick` handlers into jQuery `ready()` event bindings on the threshold, notification list, notification queue, template and device/log status pages so they no longer trip Cacti's Content-Security-Policy `script-src-attr` directive * dev: Remove the inert COMPOSER_ROOT_VERSION env from the Pest CI step * feature: Restyle the Thold, Host status and Log status legends as rounded, evenly-spaced solid-colour chips for a clearer, more readable status key across every theme * dev: Keep the status-legend chips equal width (sized to the longest label) as the legend wraps responsively diff --git a/locales/po/cacti.pot b/locales/po/cacti.pot index 913cc0c2..25c1362d 100644 --- a/locales/po/cacti.pot +++ b/locales/po/cacti.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Cacti \n" "Report-Msgid-Bugs-To: developers@cacti.net\n" -"POT-Creation-Date: 2026-09-30 21:27-0400\n" +"POT-Creation-Date: 2026-10-07 15:19-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Cacti Developers >\n" "Language-Team: Cacti Developers \n" diff --git a/notify_lists.php b/notify_lists.php index 7c3a4f08..e84b4163 100644 --- a/notify_lists.php +++ b/notify_lists.php @@ -1258,7 +1258,7 @@ function hosts($header_label) { - ' onChange='applyFilter()'> + '> @@ -1282,7 +1282,7 @@ function hosts($header_label) { - - - > + > ' title=''> - ' onClick='clearFilter()' title=''> + ' title=''> @@ -1354,6 +1354,14 @@ function clearFilter() { $('#site_id').off('change').on('change', function() { applyFilter(); }); + + $('#rfilter, #host_template_id, #rows, #associated').off('change').on('change', function() { + applyFilter(); + }); + + $('#clear').click(function() { + clearFilter(); + }); }); @@ -1636,7 +1644,7 @@ function tholds($header_label) { - ' onChange='applyFilter()'> + '> @@ -1660,7 +1668,7 @@ function tholds($header_label) { - - @@ -1685,7 +1693,7 @@ function tholds($header_label) { - - > + > ' title=''> - ' onClick='clearFilter()' title=''> + ' title=''> @@ -1738,6 +1746,14 @@ function clearFilter() { $('#site_id').off('change').on('change', function() { applyFilter(); }); + + $('#rfilter, #template, #state, #rows, #associated').off('change').on('change', function() { + applyFilter(); + }); + + $('#clear').click(function() { + clearFilter(); + }); }); @@ -1982,13 +1998,13 @@ function templates($header_label) { - ' onChange='applyFilter()'> + '> - - > + > ' title=''> - ' onClick='clearFilter()' title=''> + ' title=''> @@ -2034,6 +2050,14 @@ function clearFilter() { event.preventDefault(); applyFilter(); }); + + $('#rfilter, #rows, #associated').off('change').on('change', function() { + applyFilter(); + }); + + $('#clear').click(function() { + clearFilter(); + }); }); @@ -2343,7 +2367,7 @@ function lists() { - ' title=''> - ' title='' onClick='clearFilter()'> + ' title=''> @@ -2382,6 +2406,14 @@ function clearFilter() { event.preventDefault(); applyFilter(); }); + + $('#rows').off('change').on('change', function() { + applyFilter(); + }); + + $('#clear').click(function() { + clearFilter(); + }); }); diff --git a/notify_queue.php b/notify_queue.php index 7949e22e..366057c1 100644 --- a/notify_queue.php +++ b/notify_queue.php @@ -295,7 +295,7 @@ function notify_queue() { - - @@ -324,7 +324,7 @@ function notify_queue() { - 0) { @@ -368,6 +368,10 @@ function clearFilter() { } $(function() { + $('#topic, #processed, #rows').change(function() { + applyFilter(); + }); + $('#refresh').click(function() { applyFilter(); }); diff --git a/thold.php b/thold.php index 26934a1e..1745ec14 100644 --- a/thold.php +++ b/thold.php @@ -729,7 +729,7 @@ function list_tholds() { - ' title=''> - ' title='' onClick='clearFilter()'> + ' title=''> @@ -764,7 +764,7 @@ function list_tholds() { - - - @@ -807,7 +807,7 @@ function list_tholds() { - diff --git a/thold_graph.php b/thold_graph.php index 5676d8c9..ad4cf0f0 100644 --- a/thold_graph.php +++ b/thold_graph.php @@ -149,7 +149,7 @@ function form_thold_filter() { - '> - ' onClick='clearFilter()'> + '> @@ -184,7 +184,7 @@ function form_thold_filter() { - - - @@ -245,7 +245,7 @@ function form_thold_filter() { - - - " . __('Disabled', 'thold') . '' : ''); ?> @@ -1294,7 +1302,7 @@ function form_host_filter() { '> - ' onClick='clearFilter()'> + '> @@ -1305,7 +1313,7 @@ function form_host_filter() { - - @@ -1752,7 +1768,7 @@ function form_thold_log_filter() { - '> - ' onClick='clearFilter()'> - ' onClick='exportLog()'> + '> + '> @@ -1788,7 +1804,7 @@ function form_thold_log_filter() { - - - - diff --git a/thold_templates.php b/thold_templates.php index 67feff07..1e965db6 100644 --- a/thold_templates.php +++ b/thold_templates.php @@ -513,7 +513,7 @@ function template_add() { - $name) { print "'; @@ -561,7 +561,7 @@ function template_add() { - $name) { print "'; @@ -618,6 +618,14 @@ function applyFilter(type) { json = $('input, select').serializeObject(); loadPageUsingPost(strURL, json); }); + + $('#data_template_id').change(function() { + applyFilter('dt'); + }); + + $('#data_source_id').change(function() { + applyFilter('ds'); + }); }); @@ -2286,7 +2294,7 @@ function templates() { - - ' onClick='applyFilter()'> - ' onClick='clearFilter()'> - ' onClick='importTemplate()'> + '> + '> + '> @@ -2334,6 +2342,22 @@ function importTemplate() { event.preventDefault(); applyFilter(); }); + + $('#rows').change(function() { + applyFilter(); + }); + + $('#refresh').click(function() { + applyFilter(); + }); + + $('#clear').click(function() { + clearFilter(); + }); + + $('#import').click(function() { + importTemplate(); + }); }); From 1fdc49f8fefe18453e11958281cccc2662d49ba4 Mon Sep 17 00:00:00 2001 From: TheWitness Date: Wed, 7 Oct 2026 17:15:51 -0400 Subject: [PATCH 2/3] security: convert cactiReturnTo cancel buttons to the CSP-safe class The confirmation pages' Cancel buttons used an inline onClick='cactiReturnTo()' handler, which trips Cacti's Content-Security-Policy script-src-attr directive. Switch them to the CSP-safe cactiReturnTo CSS class (class='cactiReturnTo', plus an optional data-url when a target is passed). Cacti 1.2.31 and later bind this class automatically. The README documents a one-time include/layout.js applySkin() snippet for operators still on an earlier release - no shim is baked into the core or the plugin. --- CHANGELOG.md | 1 + README.md | 14 ++++++++++++++ notify_lists.php | 16 ++++++++-------- notify_queue.php | 2 +- thold.php | 2 +- thold_templates.php | 2 +- 6 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c28852ed..8f5737e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## ChangeLog --- develop --- +* security: Replace the confirmation pages' inline `onClick='cactiReturnTo()'` Cancel buttons with the CSP-safe `cactiReturnTo` class so they no longer trip Cacti's Content-Security-Policy `script-src-attr` directive * security: Move the filter controls' inline `onChange`/`onClick` handlers into jQuery `ready()` event bindings on the threshold, notification list, notification queue, template and device/log status pages so they no longer trip Cacti's Content-Security-Policy `script-src-attr` directive * dev: Remove the inert COMPOSER_ROOT_VERSION env from the Pest CI step * feature: Restyle the Thold, Host status and Log status legends as rounded, evenly-spaced solid-colour chips for a clearer, more readable status key across every theme diff --git a/README.md b/README.md index 7642c599..38267a8b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,20 @@ changes through Email, Syslog, and either SNMP Trap or Inform. NOTE: The Thold plugin that is in GitHub is ONLY compatible with Cacti 1.0.0 and above! +## Cacti compatibility + +If you are running a version of Cacti below 1.2.31, please add the function +below to the `applySkin()` function in `include/layout.js` to enable the Cancel +buttons on forms to work: + +```js +$(document).off('click.cactiReturnTo', '.cactiReturnTo') + .on('click.cactiReturnTo', '.cactiReturnTo', function(event) { + event.preventDefault(); + cactiReturnTo($(this).attr('data-url')); + }); +``` + ## Installation To install the plugin, simply copy the plugin_thold directory to Cacti's plugins diff --git a/notify_lists.php b/notify_lists.php index e84b4163..a5534e12 100644 --- a/notify_lists.php +++ b/notify_lists.php @@ -718,7 +718,7 @@ function form_actions() { "; - $save_html = " "; + $save_html = " "; } elseif (get_request_var('drp_action') == '2') { // duplicate print " @@ -730,7 +730,7 @@ function form_actions() { print '

'; - $save_html = " "; + $save_html = " "; } } else { raise_message(40); @@ -792,7 +792,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } elseif (get_request_var('drp_action') == '2') { // disassociate print " @@ -807,7 +807,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } } else { raise_message(40); @@ -870,7 +870,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } elseif (get_request_var('drp_action') == '2') { // disassociate print " @@ -885,7 +885,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } } else { raise_message(40); @@ -951,7 +951,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } elseif (get_request_var('drp_action') == '2') { // disassociate print " @@ -970,7 +970,7 @@ function form_actions() { '; - $save_html = " "; + $save_html = " "; } } else { raise_message(40); diff --git a/notify_queue.php b/notify_queue.php index 366057c1..7f7895d3 100644 --- a/notify_queue.php +++ b/notify_queue.php @@ -170,7 +170,7 @@ function form_actions() { "; - $save_html = " "; + $save_html = " "; } } else { raise_message(40); diff --git a/thold.php b/thold.php index 1745ec14..63468096 100644 --- a/thold.php +++ b/thold.php @@ -510,7 +510,7 @@ function do_actions() { $returnTo = $config['url_path'] . 'plugins/thold/thold.php'; } - $save_html = ""; + $save_html = ""; if (!empty($button)) { $save_html .= " "; diff --git a/thold_templates.php b/thold_templates.php index 1e965db6..82980d1d 100644 --- a/thold_templates.php +++ b/thold_templates.php @@ -327,7 +327,7 @@ function DownloadStart(url) { \n"; - $save_html = ""; + $save_html = ""; if (!empty($button)) { $save_html .= " "; From f87b1d15a1511a91840c129ff4c19c717d68bbe8 Mon Sep 17 00:00:00 2001 From: TheWitness Date: Wed, 7 Oct 2026 18:18:53 -0400 Subject: [PATCH 3/3] fix: give Thresholds/Devices filter Clear buttons the id the ready() handler binds The hosts() and tholds() filter views used name='clear' on the Clear button, but the ready() handler binds to #clear, so Clear was a no-op on those two views. Switch them to id='clear' to match the other views and the handler. --- notify_lists.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify_lists.php b/notify_lists.php index a5534e12..b5e5998f 100644 --- a/notify_lists.php +++ b/notify_lists.php @@ -1322,7 +1322,7 @@ function hosts($header_label) { ' title=''> - ' title=''> + ' title=''> @@ -1713,7 +1713,7 @@ function tholds($header_label) { ' title=''> - ' title=''> + ' title=''>