hardening: prepared statements, PHP 7.4 idioms, and security fixes#766
hardening: prepared statements, PHP 7.4 idioms, and security fixes#766somethingwithproof wants to merge 2 commits intoCacti:developfrom
Conversation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR aims to harden and modernize the thold plugin’s PHP by mechanically replacing isset() ternaries and !isset() assignment patterns with PHP 7.4+ null coalescing operators (??, ??=), primarily in UI form field defaults and a few helper paths.
Changes:
- Replaced many
isset(...) ? ... : ...patterns with??across threshold and template edit forms. - Replaced a couple of
if (!isset(...)) { ... }patterns with??=. - Minor refactors in notification list form handling to use
??defaults.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| thold.php | Refactors form field default/value assignments to use ?? (notably notification/metadata fields). |
| thold_templates.php | Similar ?? refactors for template edit form fields; includes several default/value paths. |
| thold_functions.php | Updates log/notification helper string composition to use ?? and uses ??= for $value. |
| notify_lists.php | Uses ?? in a couple of places when building saved state / injected form variables. |
| includes/arrays.php | Uses ??= to default $step from config. |
| $desc .= ' Trigger[' . plugin_thold_duration_convert($thold['data_template_id'], ($message['thold_fail_trigger'] ?? ''), 'alert', 'data_template_id') . ']'; | ||
| $desc .= ' WarnHigh[' . ($message['thold_warning_hi'] ?? '') . ']'; | ||
| $desc .= ' WarnLow[' . ($message['thold_warning_low'] ?? '') . ']'; | ||
| $desc .= ' WarnTrigger[' . plugin_thold_duration_convert($thold['data_template_id'], (isset($message['thold_warning_fail_trigger']) ? $message['thold_fail_trigger'] : ''), 'alert', 'data_template_id') . ']'; |
There was a problem hiding this comment.
In this WarnTrigger log entry, the conditional checks for thold_warning_fail_trigger but the value passed is thold_fail_trigger. This produces incorrect logging output for warning trigger duration. Use thold_warning_fail_trigger (and consider using ?? '' here for consistency with the rest of the hunk).
| $desc .= ' WarnTrigger[' . plugin_thold_duration_convert($thold['data_template_id'], (isset($message['thold_warning_fail_trigger']) ? $message['thold_fail_trigger'] : ''), 'alert', 'data_template_id') . ']'; | |
| $desc .= ' WarnTrigger[' . plugin_thold_duration_convert($thold['data_template_id'], ($message['thold_warning_fail_trigger'] ?? ''), 'alert', 'data_template_id') . ']'; |
| 'method' => 'drop_array', | ||
| 'array' => $repeatarray, | ||
| 'default' => read_config_option('alert_repeat'), | ||
| 'description' => __('Repeat alert after this amount of time has pasted since the last alert.', 'thold'), |
There was a problem hiding this comment.
Typo in user-facing string: "has pasted since the last alert" should be "has passed since the last alert".
| 'description' => __('Repeat alert after this amount of time has pasted since the last alert.', 'thold'), | |
| 'description' => __('Repeat alert after this amount of time has passed since the last alert.', 'thold'), |
| @@ -2272,7 +2272,7 @@ function thold_edit() { | |||
| 'friendly_name' => __('External ID', 'thold'), | |||
| 'method' => 'textbox', | |||
| 'description' => __('Enter an Eternal ID for this Threshold.', 'thold'), | |||
There was a problem hiding this comment.
Typo in user-facing string: "Enter an Eternal ID" should be "Enter an External ID" (matches the field label).
| 'description' => __('Enter an Eternal ID for this Threshold.', 'thold'), | |
| 'description' => __('Enter an External ID for this Threshold.', 'thold'), |
| @@ -1797,7 +1797,7 @@ function template_edit() { | |||
| 'friendly_name' => __('External ID', 'thold'), | |||
| 'method' => 'textbox', | |||
| 'description' => __('Enter an Eternal ID for this Thold Template.', 'thold'), | |||
There was a problem hiding this comment.
Typo in user-facing string: "Enter an Eternal ID" should be "Enter an External ID" (matches the field label).
| 'description' => __('Enter an Eternal ID for this Thold Template.', 'thold'), | |
| 'description' => __('Enter an External ID for this Thold Template.', 'thold'), |
| 'method' => 'textbox', | ||
| 'max_length' => 3, | ||
| 'size' => 15, | ||
| 'description' => __('Number of consecutive times the Data Source must be in a breached condition for an alert to be raised.<br>Leave empty to use default value (Default: %s cycles', read_config_option('alert_bl_trigger'), 'thold'), |
There was a problem hiding this comment.
This description string appears to be missing a closing parenthesis (and/or closing markup) after "Default: %s cycles" which will render oddly in the UI.
| 'description' => __('Number of consecutive times the Data Source must be in a breached condition for an alert to be raised.<br>Leave empty to use default value (Default: %s cycles', read_config_option('alert_bl_trigger'), 'thold'), | |
| 'description' => __('Number of consecutive times the Data Source must be in a breached condition for an alert to be raised.<br>Leave empty to use default value (Default: %s cycles)', read_config_option('alert_bl_trigger'), 'thold'), |
| 'default' => read_config_option('thold_warning_time_fail_trigger'), | ||
| 'description' => __('The number of times the Data Source must be in breach condition prior to issuing a warning.', 'thold'), | ||
| 'value' => isset($thold_data['time_warning_fail_trigger']) ? $thold_data['time_warning_fail_trigger'] : read_config_option('alert_trigger') | ||
| 'value' => $thold_data['time_warning_fail_trigger'] ?? read_config_option('alert_trigger') |
There was a problem hiding this comment.
The time_warning_fail_trigger field sets its default from thold_warning_time_fail_trigger, but when the value is absent it falls back to alert_trigger. This makes the displayed/defaulted value inconsistent with the configured default for this field; align the fallback with the default option.
| 'value' => $thold_data['time_warning_fail_trigger'] ?? read_config_option('alert_trigger') | |
| 'value' => $thold_data['time_warning_fail_trigger'] ?? read_config_option('thold_warning_time_fail_trigger') |
| 'array' => $timearray, | ||
| 'description' => __('The amount of time in the past to check for Threshold breaches.', 'thold'), | ||
| 'value' => isset($thold_data['time_warning_fail_length']) ? $thold_data['time_warning_fail_length'] : (read_config_option('thold_time_fail_length') > 0 ? read_config_option('thold_warning_time_fail_length') : 1) | ||
| 'value' => $thold_data['time_warning_fail_length'] ?? (read_config_option('thold_time_fail_length') > 0 ? read_config_option('thold_warning_time_fail_length') : 1) |
There was a problem hiding this comment.
time_warning_fail_length falls back using a condition on thold_time_fail_length, but returns thold_warning_time_fail_length. This looks like a copy/paste error and can cause the warning default to depend on the alert setting; the condition should likely check the warning option as well.
| 'value' => $thold_data['time_warning_fail_length'] ?? (read_config_option('thold_time_fail_length') > 0 ? read_config_option('thold_warning_time_fail_length') : 1) | |
| 'value' => $thold_data['time_warning_fail_length'] ?? (read_config_option('thold_warning_time_fail_length') > 0 ? read_config_option('thold_warning_time_fail_length') : 1) |
| if (!isset($step)) { | ||
| $step = read_config_option('poller_interval'); | ||
| } | ||
| $step ??= read_config_option('poller_interval'); |
There was a problem hiding this comment.
PR description mentions prepared statements / SQL parameterization and RLIKE/LIKE injection fixes, but the changes in this PR appear limited to ?? / ??= mechanical refactors in the touched files. Either update the PR description to match the actual changes, or include the intended SQL hardening changes in this PR.
| 'max_length' => 128, | ||
| 'description' => __('This is the Warning Email subject that will be displayed in the Email after change to Warning (128 Char MAX). Leave blank for the default. There are several common replacement tags that may be used in include:<br><PHASE> <THRESHOLDVALUE> <CURRENTVALUE> <THRESHOLDNAME> <DSNAME> <BREACHUP> <REALERT> <HOSTNAME> <LOCATION> <SITE>', 'thold'), | ||
| 'value' => isset($thold_data['email_subject']) ? $thold_data['email_subject'] : '' | ||
| 'value' => $thold_data['email_subject'] ?? '' |
There was a problem hiding this comment.
The email_subject_warn form field is populated from $thold_data['email_subject'] instead of $thold_data['email_subject_warn']. This causes the Warning Subject UI to display (and potentially save) the Alert Subject value, overwriting the real warning subject.
| 'value' => $thold_data['email_subject'] ?? '' | |
| 'value' => $thold_data['email_subject_warn'] ?? '' |
| 'max_length' => 128, | ||
| 'description' => __('This is the Warning subject that will be displayed in the Email (128 Char MAX). Leave blank for the default. There are several common replacement tags that may be used in include:<br><PHASE> <THRESHOLDVALUE> <CURRENTVALUE> <THRESHOLDNAME> <DSNAME> <BREACHUP> <REALERT> <HOSTNAME>', 'thold'), | ||
| 'value' => isset($thold_data['email_subject']) ? $thold_data['email_subject'] : '' | ||
| 'value' => $thold_data['email_subject'] ?? '' |
There was a problem hiding this comment.
The email_subject_warn form field is populated from $thold_data['email_subject'] instead of $thold_data['email_subject_warn']. This causes the Warning Subject UI to display (and potentially save) the Alert Subject value, overwriting the real warning subject.
| 'value' => $thold_data['email_subject'] ?? '' | |
| 'value' => $thold_data['email_subject_warn'] ?? '' |
…rplate Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
e265860 to
2f29161
Compare
Consolidated hardening PR:
5 files changed, 146 insertions(+), 150 deletions(-)
All changes are mechanical transforms with zero behavioral impact. PHP 7.4+ compatible.