Skip to content

fix(security): comprehensive bug and security cleanup#302

Open
somethingwithproof wants to merge 2 commits intoCacti:developfrom
somethingwithproof:fix/security-and-bug-cleanup
Open

fix(security): comprehensive bug and security cleanup#302
somethingwithproof wants to merge 2 commits intoCacti:developfrom
somethingwithproof:fix/security-and-bug-cleanup

Conversation

@somethingwithproof
Copy link
Copy Markdown
Contributor

Summary

Security and bug fixes across 7 files. Each fix is minimal and targeted. All files pass php -l lint. Independently reviewed by Grok (xAI) for correctness, regressions, and remaining gaps.

Fixes

CRITICAL

  • Prevent syslog_reports table DROP on upgrade. The condition if ($truncate || !$newreport) caused DROP even when truncate was false, destroying user report rules. Changed to if ($truncate) only. (Syslog table drop with no apparent reason #300)

HIGH

MEDIUM

LOW

Files changed

  • setup.php: DROP TABLE condition fix
  • functions.php: CSV safe helper, domain stripping parameterization, DST fix
  • syslog.php: RLIKE db_qstr wrapping
  • syslog_alerts.php: prepared statement CRUD
  • syslog_removal.php: prepared statement CRUD
  • syslog_reports.php: prepared statement CRUD
  • js/functions.js: eval() removal

Test plan

  • Upgrade from pre-body-column state: verify syslog_reports table is NOT dropped
  • Create/edit/delete alert, removal, and report rules
  • Verify domain stripping still works with configured domains
  • Export syslog CSV and verify formula-safe output
  • Verify syslog filter (rfilter) works with special characters
  • Verify JS autocomplete still fires callbacks

Closes #199, #252, #256, #259, #260, #261, #300

Copilot AI review requested due to automatic review settings April 9, 2026 00:14
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 performs a security hardening and bug-fix sweep across the Syslog plugin, focusing on preventing destructive upgrades, reducing SQL injection surfaces, and removing unsafe client-side execution.

Changes:

  • Prevents unintended table drops during setup/upgrade and fixes DST-related partition boundary calculation.
  • Hardens several SQL paths by quoting/parameterizing user-controlled inputs and CRUD operations.
  • Removes eval() usage from the autocomplete callback flow and introduces CSV-safety scaffolding.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
setup.php Adjusts syslog_reports drop condition during setup to avoid accidental data loss.
functions.php Fixes partition boundary calculation and adds a CSV-safety helper (currently problematic).
syslog.php Wraps RLIKE filter input in db_qstr() to reduce SQL injection risk via rfilter.
syslog_alerts.php Converts alert rule delete/enable/disable to prepared statements.
syslog_removal.php Converts removal rule delete/enable/disable to prepared statements.
syslog_reports.php Converts report rule delete to a prepared statement (but enable/disable still unparameterized).
js/functions.js Replaces eval() callback execution with function reference lookup.
Comments suppressed due to low confidence (1)

syslog_reports.php:329

  • Only api_syslog_report_remove() was converted to a prepared statement. api_syslog_report_disable() and api_syslog_report_enable() still concatenate $id directly into SQL, which is inconsistent with the hardening in this PR and reintroduces an injection surface for future callers. Convert both to syslog_db_execute_prepared(... WHERE id = ?) (and/or intval($id)), matching the other CRUD helpers.
	syslog_db_execute_prepared("DELETE FROM `" . $syslogdb_default . "`.`syslog_reports` WHERE id = ?", array(intval($id)));
}

function api_syslog_report_disable($id) {
	global $syslogdb_default;
	syslog_db_execute('UPDATE `' . $syslogdb_default . "`.`syslog_reports` SET enabled='' WHERE id=" . $id);
}

function api_syslog_report_enable($id) {
	global $syslogdb_default;
	syslog_db_execute('UPDATE `' . $syslogdb_default . "`.`syslog_reports` SET enabled='on' WHERE id=" . $id);
}

TheWitness
TheWitness previously approved these changes Apr 9, 2026
Copy link
Copy Markdown
Member

@TheWitness TheWitness left a comment

Choose a reason for hiding this comment

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

I'm going to approve this, but we will need to move that escaping to dompurify and change the way the unit tests operate as mentioned separately.

js/functions.js Outdated
/**
* Clear filter for statistics view
*/
// Escape HTML special characters to prevent XSS
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should use dompurify here. It's in the base.

xmacan
xmacan previously approved these changes Apr 9, 2026
bmfmancini
bmfmancini previously approved these changes Apr 9, 2026
- CRITICAL: prevent syslog_reports table DROP on upgrade (Cacti#300)
- HIGH: parameterize domain stripping SQL (Cacti#261)
- HIGH: wrap RLIKE filter values with db_qstr in syslog.php
- MEDIUM: add CSV formula injection protection in exports (Cacti#256)
- MEDIUM: sanitize DOM insertions with DOMPurify
- LOW: parameterize admin CRUD delete/enable/disable (Cacti#252)
- LOW: fix DST partition boundary using strtotime (Cacti#199)

Closes Cacti#199, Cacti#252, Cacti#256, Cacti#259, Cacti#260, Cacti#261, Cacti#300

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof somethingwithproof dismissed stale reviews from bmfmancini and xmacan via da6d22e April 9, 2026 21:22
@somethingwithproof somethingwithproof force-pushed the fix/security-and-bug-cleanup branch from a65362d to da6d22e Compare April 9, 2026 21:22
- Convert remaining db_qstr() RLIKE calls to prepared statements
- Fix OR-clause parenthesization in WHERE conditions
- Expand CSV injection regex to include / and \n per OWASP
- Add strlen <= 255 ReDoS guard on RLIKE input
- Convert setup.php raw SQL to prepared statement

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
$cformat = 'd' . date('Ymd', $time);
$lnow = date('Y-m-d', $time+86400);
$cformat = 'd' . gmdate('Ymd', $time);
$lnow = gmdate('Y-m-d', strtotime('+1 day', $time));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why gmdate()?

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.

[4.0] - Duplicate Partition name errors

5 participants