From c64f592a019feedfc7c232fcc549c2cb93d10d7e Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Sun, 16 Aug 2026 23:17:31 -0700 Subject: [PATCH 1/2] ci: repair the integration workflow Three defects, all failing open or failing at setup: - the plugin syntax check redirected find's own output rather than php's, so PHP errors never reached the grep testing for them; the step could not fail - MYSQL_AUTH_USR carried a literal tilde, because parameter expansion happens after tilde expansion, so MySQL was handed a path it could not resolve - the Cacti checkout took the default branch, which is 1.3 in development and whose CLI installer currently fatals with an undefined __() plugin_syslog additionally installed libapache2-mod-php${{ matrix.php }}, which Ubuntu does not package, so apt exited 100 before Cacti was reached. Verified with actionlint, which is clean on the result. Signed-off-by: Thomas Vincent --- .github/workflows/plugin-ci-workflow.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 86237dc..265b555 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -40,6 +40,7 @@ jobs: uses: actions/checkout@v4 with: repository: Cacti/cacti + ref: release/1.2.31 path: cacti - name: Checkout Syslog Plugin @@ -57,7 +58,7 @@ jobs: - name: Check PHP Syntax (Lint) run: | cd cacti/plugins/syslog - if find . -name '*.php' -not -path './vendor/*' -exec php -l {} 2>&1 \; | grep -iv 'no syntax errors detected'; then + if find . -name '*.php' -not -path './vendor/*' -exec php -l {} \; 2>&1 | grep -iv 'no syntax errors detected'; then echo "Syntax errors found!" exit 1 fi @@ -122,6 +123,7 @@ jobs: uses: actions/checkout@v4 with: repository: Cacti/cacti + ref: release/1.2.31 path: cacti - name: Checkout Syslog Plugin @@ -143,7 +145,7 @@ jobs: run: sudo apt-get update - name: Install System Dependencies - run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping libapache2-mod-php${{ matrix.php }} + run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping libapache2-mod-php - name: Start SNMPD Agent and Test run: | @@ -163,16 +165,15 @@ jobs: echo -e "[client]\nuser = root\npassword = cactiroot\nhost = 127.0.0.1\n" > ~/.my.cnf - name: Initialize Cacti Database - env: - MYSQL_AUTH_USR: '--defaults-file=~/.my.cnf' run: | - mysql $MYSQL_AUTH_USR -e 'CREATE DATABASE IF NOT EXISTS cacti;' - mysql $MYSQL_AUTH_USR -e "CREATE USER IF NOT EXISTS 'cactiuser'@'localhost' IDENTIFIED BY 'cactiuser';" - mysql $MYSQL_AUTH_USR -e "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost';" - mysql $MYSQL_AUTH_USR -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost';" - mysql $MYSQL_AUTH_USR -e "FLUSH PRIVILEGES;" - mysql $MYSQL_AUTH_USR cacti < ${{ github.workspace }}/cacti/cacti.sql - mysql $MYSQL_AUTH_USR -e "INSERT INTO settings (name, value) VALUES ('path_php_binary', '/usr/bin/php')" cacti + MYSQL_AUTH_USR="--defaults-file=$HOME/.my.cnf" + mysql "$MYSQL_AUTH_USR" -e 'CREATE DATABASE IF NOT EXISTS cacti;' + mysql "$MYSQL_AUTH_USR" -e "CREATE USER IF NOT EXISTS 'cactiuser'@'localhost' IDENTIFIED BY 'cactiuser';" + mysql "$MYSQL_AUTH_USR" -e "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost';" + mysql "$MYSQL_AUTH_USR" -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost';" + mysql "$MYSQL_AUTH_USR" -e "FLUSH PRIVILEGES;" + mysql "$MYSQL_AUTH_USR" cacti < ${{ github.workspace }}/cacti/cacti.sql + mysql "$MYSQL_AUTH_USR" -e "INSERT INTO settings (name, value) VALUES ('path_php_binary', '/usr/bin/php')" cacti - name: Validate composer files run: | From 6763bf7843c0cc48b0f9cedd96ef1ee582d992c7 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 17 Aug 2026 15:11:40 -0700 Subject: [PATCH 2/2] Document PHP 8 hardening and CI behavior --- CHANGELOG.md | 14 ++++++++++++++ README.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a22b42..3a0fe9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ --- develop --- +* security: Require POST and CSRF validation for unused-host purge + operations +* security: Escape HTML and JavaScript output contexts and restrict callback + dispatch to bare identifiers +* security: Defuse spreadsheet formulas in CSV output while retaining + `fputcsv()` quoting +* security: Limit pasted and uploaded XML rule imports to 5 MiB before + parsing +* issue: Use integer UTC partition boundaries and preserve `dMaxValue` as a + fail-safe write partition +* test: Add standalone security regressions and Docker/Playwright end-to-end + coverage +* ci: Validate the plugin on Linux with PHP 8.1-8.3 and pinned Cacti + `release/1.2.31` * issue#199: Duplicate Partition name errors * issue#250: Fix date filter persistence by validating before shift_span detection * issue#252: hardening: escape device hostname output in syslog view; parameterize alert API functions diff --git a/README.md b/README.md index 0e12b30..7c5c186 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,59 @@ However, in Syslog Version 4, if you want an alert per Host, you will have to move your Alerts from the `System Level` to the `Host Level` as `System Level` Alerts will generate one command execution for all matching messages. +## Develop Branch Compatibility and Hardening Notes + +The following behavior is part of the hardening work being prepared on the +`develop` branch for the next release. Released versions may not include every +item yet. + +### Runtime and Test Baseline + +The hardened code paths use PHP 8.0-compatible language features and require +PHP 8.0 or later. The Linux integration workflow currently exercises PHP 8.1, +8.2, and 8.3 against Cacti `release/1.2.31`, including installation, plugin +enablement, polling, and sample Syslog processing. + +This plugin does not ship its own `composer.json`. Composer validation and +dependency installation in CI use the manifest supplied by the checked-out +Cacti core release. + +### Security-Sensitive Behavior + +* Purging unused Syslog hosts requires a POST request and a valid Cacti CSRF + token. The operation fails closed when CSRF validation is unavailable. + +* Alert, navigation, and JavaScript-bound values are escaped for their output + context. JavaScript callback dispatch accepts only a bare function identifier + with no arguments or dotted path. + +* CSV exports continue to use PHP's `fputcsv()` for quoting. Cells beginning + with spreadsheet formula markers (`=`, `+`, `-`, `@`, tab, or carriage + return), including markers after leading spaces, are prefixed with a single + quote before export. + +* XML rule imports accept either pasted text or an uploaded file. Both paths + enforce a 5 MiB payload limit before XML parsing; rejected payloads are logged + and redirected without being parsed. + +* Legacy SQL-expression rules remain trusted administrator configuration. Do + not grant rule-management permissions to untrusted users, and review custom + SQL expressions before enabling them. + +### Partition Maintenance + +Partition boundaries are calculated with integer UTC epoch arithmetic. When a +new partition cannot be created safely, maintenance leaves the `dMaxValue` +partition in place and skips retention pruning rather than risking a write gap. + +### Validation + +The repository includes standalone PHP security regressions and a disposable +Docker/Playwright end-to-end harness. GitHub CI runs PHP syntax and quality +checks, CodeQL, and the PHP 8.1-8.3 integration matrix on Linux. The Docker E2E +runner refuses unsafe temporary-directory paths before performing recursive +cleanup. + ## Installation To install the syslog plugin, simply copy the plugin_syslog directory to Cacti's