Skip to content

fix(security): defense-in-depth hardening for plugin_thold#767

Draft
somethingwithproof wants to merge 7 commits intoCacti:developfrom
somethingwithproof:fix/defense-in-depth
Draft

fix(security): defense-in-depth hardening for plugin_thold#767
somethingwithproof wants to merge 7 commits intoCacti:developfrom
somethingwithproof:fix/defense-in-depth

Conversation

@somethingwithproof
Copy link
Copy Markdown

@somethingwithproof somethingwithproof commented Apr 9, 2026

Summary

Automated defense-in-depth hardening for plugin_thold, with the latest pass focused on concrete request-handling and output-encoding issues in notify_lists.php.

  • escape drp_action and id when they are reused in hidden form fields
  • cast list IDs in notify-list JavaScript and navigation links before emitting them back into the page
  • harden the threshold-association listing by casting numeric request inputs and quoting the RLIKE filter via db_qstr()
  • keep the branch PHP 7.4-friendly and aligned with Cacti 1.2-style narrow fixes

Test plan

  • php -l notify_lists.php
  • php tests/unit/test_notify_list_security_guards.php
  • php tests/integration/test_notify_list_wiring.php
  • php tests/e2e/test_notify_list_no_raw_sql_or_form_reuse.php

Notes

This update is intentionally narrow. It does not attempt a broad rewrite of notify_lists.php; it only removes the concrete raw SQL/form/JS reuse that remained live in the notify-list association flows.

Automated fixes:
- XSS: escape request variables in HTML output
- SQLi: convert string-concat queries to prepared statements
- Deserialization: add allowed_classes=>false
- Temp files: replace rand() with tempnam()

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Copilot AI review requested due to automatic review settings April 9, 2026 06:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Defense-in-depth security hardening for the Thold plugin, focusing on reducing common web attack surfaces (XSS/object injection) in request handling and data decoding paths.

Changes:

  • Tighten deserialization by adding allowed_classes => false on cacti_unserialize() usage.
  • Reduce XSS risk by escaping request vars before placing them into HTML value attributes.
  • Harden request-derived IDs used in JavaScript requests/URLs by filtering and casting to integers.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
thold_webapi.php Attempts to harden unserialize of selected_graphs_array (currently introduces an argument-mismatch bug).
thold_process.php Uses allowed_classes => false when unserializing stored rrd_reindexed data.
thold_graph.php Escapes page request var before embedding into hidden inputs.
setup.php Filters/casts request IDs before embedding them into JS POST bodies and URLs.
notify_lists.php Filters/casts request ID before embedding it into JS-generated filter URLs.

thold_webapi.php Outdated
$return_array = false;

$selected_graphs_array = cacti_unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array')));
$selected_graphs_array = cacti_unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array', array('allowed_classes' => false))));
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_nfilter_request_var() is being called with a second argument (array('allowed_classes' => false)), but this codebase otherwise only calls it with a single parameter. This is likely a runtime error (too many arguments) and also doesn’t apply the allowed_classes restriction to the unserialize operation. Pass the options array to cacti_unserialize() instead (second parameter), and keep get_nfilter_request_var('selected_graphs_array') as-is.

Suggested change
$selected_graphs_array = cacti_unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array', array('allowed_classes' => false))));
$selected_graphs_array = cacti_unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array')), array('allowed_classes' => false));

Copilot uses AI. Check for mistakes.
Replace .click(fn) with .on('click', fn), .change(fn) with
.on('change', fn), .submit(fn) with .on('submit', fn), .unbind()
with .off(), and .resize(fn) with .on('resize', fn).

These shorthands were deprecated in jQuery 3.3 and will be removed
in jQuery 4.0. Cacti core ships jQuery 3.x on develop.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
- Change Dependabot ecosystem from npm to composer (PHP-only repo)
- Remove PHP from CodeQL paths-ignore so security PRs get analysis
- Remove committed .omc session artifacts, add .omc/ to .gitignore

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
The function was called via inline onClick, but it just bound another
click handler - which never fired because the click event had already
completed. Execute the POST directly in the function.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof somethingwithproof marked this pull request as draft April 11, 2026 00:10
@somethingwithproof
Copy link
Copy Markdown
Author

Converted to draft to serialize the stack in this repo. Blocked by #766; will un-draft after that merges to avoid cross-PR merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants