Skip to content

hardening: enforce POST+CSRF for purge syslog devices utility#265

Open
somethingwithproof wants to merge 1 commit intoCacti:developfrom
somethingwithproof:hardening/csrf-purge-utility
Open

hardening: enforce POST+CSRF for purge syslog devices utility#265
somethingwithproof wants to merge 1 commit intoCacti:developfrom
somethingwithproof:hardening/csrf-purge-utility

Conversation

@somethingwithproof
Copy link
Contributor

@somethingwithproof somethingwithproof commented Mar 6, 2026

Summary

  • require POST before executing the purge_syslog_hosts utility action
  • explicitly validate CSRF tokens using csrf_check(false) (with __csrf_magic fallback if csrf helper is unavailable)
  • replace the GET action link in utilities UI with a JS POST flow that includes __csrf_magic
  • add regression coverage for purge CSRF hardening
  • run regression scripts from CI when tests/regression/*.php exist
  • add changelog entry for issue hardening: require POST + CSRF token for purge_syslog_hosts utility action #259

Validation

  • php -l setup.php
  • php -l tests/regression/issue259_csrf_purge_test.php
  • php tests/regression/issue259_csrf_purge_test.php

Fixes #259

Copilot AI review requested due to automatic review settings March 6, 2026 22:04
Copy link
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

Hardens the Syslog plugin’s “Purge Syslog Devices” utility by requiring the action to be executed via a POST flow intended to include CSRF protection, rather than a direct GET link, preserving the existing redirect/message behavior after execution.

Changes:

  • Added a server-side POST + __csrf_magic presence check before running purge_syslog_hosts.
  • Replaced the utilities UI GET link with a button-driven JS POST flow that submits action=purge_syslog_hosts plus CSRF token data.
  • Kept the post-action redirect back to utilities.php with UI messaging.

setup.php Outdated
Comment on lines +1569 to +1571
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['__csrf_magic'])) {
raise_message('syslog_error', __('Invalid request. This action requires a CSRF protected POST.', 'syslog'), MESSAGE_LEVEL_ERROR);
header('Location: utilities.php');
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

PR metadata says this change “Fixes #255”, but issue #255 is about SQL concatenation in the legacy syslog_manage_items() batch path (e.g., message LIKE '%...%' / type='sql' clauses in functions.php). This PR only hardens the utilities purge action flow, so it doesn’t appear to address the referenced issue as described. Either update the PR description/linked issue, or include the SQL hardening changes for #255 in this PR.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

PR references #259 (CSRF purge), not #255. The issue number in the description is correct.

setup.php Outdated
Comment on lines +1569 to +1573
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['__csrf_magic'])) {
raise_message('syslog_error', __('Invalid request. This action requires a CSRF protected POST.', 'syslog'), MESSAGE_LEVEL_ERROR);
header('Location: utilities.php');
exit;
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The current CSRF gate only checks for the presence of __csrf_magic and does not validate the token value. If CSRF-magic isn’t already enforcing server-side validation for this endpoint, an attacker could supply an arbitrary __csrf_magic value and still pass this check. Prefer invoking the standard Cacti CSRF validation mechanism for POST actions (or otherwise explicitly validate the token), while keeping the POST-only requirement.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Primary validation uses csrf_check(false) when available; the __csrf_magic presence check is the fallback for environments without the csrf helper.

@somethingwithproof
Copy link
Contributor Author

Addressed review feedback in the latest commit set:

  • corrected issue linkage to Fixes #259
  • enforced POST-only request handling for purge action
  • added explicit CSRF token validation via csrf_check(false)
  • added regression coverage (tests/regression/issue259_csrf_purge_test.php) and CI regression execution

@somethingwithproof somethingwithproof force-pushed the hardening/csrf-purge-utility branch from 5c69e61 to a458c87 Compare March 7, 2026 13:37
Copy link
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.

We don't use confirm in Cacti. We should likely have a confirm plugin like with Bootstrap that generates a jQuery Dialog though. If you can make that happen, then this can be merged.

I'm wondering though, if the purge button can simply have it's action switched to loadPageUsingPost() and then the CSRF handling will be automatic. I think Claude screwed up on this one.

@somethingwithproof somethingwithproof force-pushed the hardening/csrf-purge-utility branch from 3dc734f to 670023c Compare March 10, 2026 20:30
@somethingwithproof
Copy link
Contributor Author

Understood -- will replace the native confirm() with a jQuery UI dialog to match Cacti conventions.

@somethingwithproof
Copy link
Contributor Author

Replaced confirm() with a jQuery UI dialog matching the displayDialog() pattern from plugins.php.

@somethingwithproof somethingwithproof force-pushed the hardening/csrf-purge-utility branch from a79581e to dae1eb6 Compare March 10, 2026 20:55
Refs Cacti#259

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof somethingwithproof force-pushed the hardening/csrf-purge-utility branch from dae1eb6 to aed2c4d Compare March 11, 2026 12:38
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.

hardening: require POST + CSRF token for purge_syslog_hosts utility action

3 participants