Skip to content

fix(thold): correct trigger_cmd variable references for low/normal states#765

Closed
somethingwithproof wants to merge 2 commits intoCacti:developfrom
somethingwithproof:fix/bug-batch
Closed

fix(thold): correct trigger_cmd variable references for low/normal states#765
somethingwithproof wants to merge 2 commits intoCacti:developfrom
somethingwithproof:fix/bug-batch

Conversation

@somethingwithproof
Copy link
Copy Markdown

Summary

Fix trigger command environment variable bug where the breach_down and breach_norm code paths used trigger_cmd_high instead of trigger_cmd_low and trigger_cmd_norm respectively.

This caused low and normal threshold trigger commands to receive the high threshold command's environment variables, producing incorrect command execution context.

Test plan

  • Configure a threshold with separate high/low/normal trigger commands
  • Trigger each state and verify the correct command environment is used

Closes #760

Wrap all get_request_var('rfilter') values with db_qstr() in RLIKE
SQL clauses across thold.php, thold_graph.php, and notify_lists.php.
10 sites total.

RLIKE accepts regex from rfilter which passes FILTER_VALIDATE_IS_REGEX
but is not SQL-safe. A single quote breaks the SQL string context.

Closes Cacti#761, Cacti#763

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
…ates

thold_set_environ() for the breach_down path used trigger_cmd_high
instead of trigger_cmd_low, and the breach_norm path also used
trigger_cmd_high instead of trigger_cmd_norm. This caused low and
normal threshold trigger commands to receive the high threshold
command's environment variables.

Closes Cacti#760

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Copilot AI review requested due to automatic review settings April 9, 2026 00:48
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

This PR aims to fix incorrect trigger-command environment handling in thold_command_execution() and also hardens several RLIKE SQL filters against injection by quoting/preparing the rfilter input.

Changes:

  • Update thold_command_execution() to pass trigger_cmd_low / trigger_cmd_norm into thold_set_environ() for breach-down and breach-normal paths.
  • Quote rfilter values in multiple RLIKE SQL fragments using db_qstr().
  • Convert some notification list queries to prepared statements (db_fetch_*_prepared) with RLIKE ? placeholders.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
thold.php Quotes rfilter in RLIKE filter to reduce SQL injection risk.
thold_graph.php Quotes rfilter in multiple RLIKE filters (thresholds, hosts, log views/exports).
thold_functions.php Changes which trigger command string is passed to thold_set_environ() for low/normal paths.
notify_lists.php Quotes rfilter in a RLIKE filter; switches some list/template queries to prepared statements.

Comment on lines 4008 to 4013
} elseif ($breach_down && $thold_data['trigger_cmd_low'] != '') {
$cmd = thold_replace_threshold_tags($thold_data['trigger_cmd_low'], $thold_data, $h, $thold_data['lastread'], $thold_data['local_graph_id'], $data_source_name);
$cmd = thold_expand_string($thold_data, $cmd);

$environment = thold_set_environ($thold_data['trigger_cmd_high'], $thold_data, $h, $thold_data['lastread'], $thold_data['local_graph_id'], $data_source_name);
$environment = thold_set_environ($thold_data['trigger_cmd_low'], $thold_data, $h, $thold_data['lastread'], $thold_data['local_graph_id'], $data_source_name);

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.

thold_set_environ() currently does not reference its $text argument (it sets a fixed set of THOLD_* vars), so switching the call sites from trigger_cmd_high to trigger_cmd_low/trigger_cmd_norm does not change the generated environment. If the intent is for the environment to be derived from the specific trigger command, the logic needs to be implemented inside thold_set_environ() (or the unused parameter removed and the PR/issue description adjusted accordingly).

Copilot uses AI. Check for mistakes.

if (get_request_var('rfilter') != '') {
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE '" . get_request_var('rfilter') . "'";
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
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.

This concatenation ends with . "", which is a no-op and makes the SQL assembly harder to read. Consider removing the trailing empty-string concatenation.

Suggested change
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE " . db_qstr(get_request_var('rfilter'));

Copilot uses AI. Check for mistakes.

if (get_request_var('rfilter') != '') {
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE '" . get_request_var('rfilter') . "'";
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
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.

This concatenation ends with . "", which is a no-op and makes the SQL assembly harder to read. Consider removing the trailing empty-string concatenation.

Suggested change
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
$sql_where .= ($sql_where == '' ? '(' : ' AND ') . ' td.name_cache RLIKE ' . db_qstr(get_request_var('rfilter'));

Copilot uses AI. Check for mistakes.

if (get_request_var('rfilter') != '') {
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE '" . get_request_var('rfilter') . "'";
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter')) . "";
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.

This concatenation ends with . "", which is a no-op and makes the SQL assembly harder to read. Consider removing the trailing empty-string concatenation.

Suggested change
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter')) . "";
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter'));

Copilot uses AI. Check for mistakes.

if (get_request_var('rfilter') != '') {
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE '" . get_request_var('rfilter') . "'";
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter')) . "";
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.

This concatenation ends with . "", which is a no-op and makes the SQL assembly harder to read. Consider removing the trailing empty-string concatenation.

Suggested change
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter')) . "";
$sql_where .= ($sql_where == '' ? '' : ' AND') . " tl.description RLIKE " . db_qstr(get_request_var('rfilter'));

Copilot uses AI. Check for mistakes.

if (strlen(get_request_var('rfilter'))) {
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . "td.name_cache RLIKE '" . get_request_var('rfilter') . "'";
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . "td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
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.

This concatenation ends with . "", which is a no-op and makes the SQL assembly harder to read. Consider removing the trailing empty-string concatenation.

Suggested change
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . "td.name_cache RLIKE " . db_qstr(get_request_var('rfilter')) . "";
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . 'td.name_cache RLIKE ' . db_qstr(get_request_var('rfilter'));

Copilot uses AI. Check for mistakes.
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.

Bug: low/normal trigger command environments are built from trigger_cmd_high

2 participants