diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c0e770..f812827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ --- 3.3 --- +* security: Replace the confirmation-page Cancel buttons' inline `onClick='cactiReturnTo()'` with the CSP-safe `cactiReturnTo` class so the pages no longer trip Cacti's Content-Security-Policy script-src-attr directive; see the README for the one-time `applySkin()` snippet needed when running Cacti below 1.2.31 (1.2.31+ binds the class automatically) * compat: Lower the minimum Cacti compatibility floor from 1.2.32 to 1.2.29 * issue: Re-introduce the `plugin_webseer_contacts` `user_id_type` UNIQUE key (on `user_id`, `type`) that Cacti 1.2.29-1.2.31's `db_update_table()` silently dropped - those releases rebuild a table's indexes only from its `keys` definition and ignore `unique_keys`. The repair runs automatically on upgrade when running one of those releases and is a no-op on 1.2.32+. WARNING: if duplicate `(user_id, type)` contact rows were inserted while the constraint was absent, re-adding the key fails; the upgrade logs the affected table and leaves the recorded version unchanged so it retries on the next request. To recover, de-duplicate `plugin_webseer_contacts` (keep a single row per `user_id`/`type`) and re-run the upgrade. Sites already upgraded to 1.2.32+ that lost the key on an earlier 1.2.29-1.2.31 run are not auto-repaired * feature: Add a root `manifest.json` and an upgrade-time file prune that removes dev-only bundled files (e.g. `tests/`) on a version change, refuses any path resolving outside the plugin directory, and logs anything it cannot remove diff --git a/README.md b/README.md index e0b90c3..ae34f90 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,20 @@ plugin so you can setup maintenance schedules so that known times when a service is going to be down can be configured so that escallation does not needlessly take place during maintenance periods. +## Cacti compatibility + +If you are running a version of Cacti below 1.2.31, please add the function +below to the `applySkin()` function in `include/layout.js` to enable the Cancel +buttons on forms to work: + +```js +$(document).off('click.cactiReturnTo', '.cactiReturnTo') + .on('click.cactiReturnTo', '.cactiReturnTo', function(event) { + event.preventDefault(); + cactiReturnTo($(this).attr('data-url')); + }); +``` + ## Installation To install the webseer plugin, simply copy the plugin_webseer directory to diff --git a/tests/Security/CspCancelButtonsTest.php b/tests/Security/CspCancelButtonsTest.php new file mode 100644 index 0000000..43cd466 --- /dev/null +++ b/tests/Security/CspCancelButtonsTest.php @@ -0,0 +1,50 @@ + 4, + 'webseer_servers.php' => 3, + 'webseer_proxies.php' => 1, +); + +it('has removed every inline cactiReturnTo onClick handler', function () use ($cancel_button_files) { + foreach (array_keys($cancel_button_files) as $file) { + $source = plugin_test_read_source($file); + + expect($source)->not->toMatch('/onClick\s*=\s*[\'"]cactiReturnTo\(/i', "{$file} still contains an inline cactiReturnTo onClick handler"); + } +}); + +it('binds every Cancel button through the CSP-safe cactiReturnTo class', function () use ($cancel_button_files) { + $total = 0; + + foreach ($cancel_button_files as $file => $expected) { + $source = plugin_test_read_source($file); + + $count = preg_match_all('/class\s*=\s*[\'"]cactiReturnTo[\'"]/i', $source); + + expect($count)->toBe($expected, "{$file} should expose {$expected} cactiReturnTo class button(s), found {$count}"); + + $total += $count; + } + + expect($total)->toBe(8); +}); diff --git a/webseer.php b/webseer.php index 525beee..d580c95 100644 --- a/webseer.php +++ b/webseer.php @@ -214,7 +214,7 @@ function form_actions() { \n"; - $save_html = " "; + $save_html = " "; } elseif ($action == WEBSEER_ACTION_URL_DISABLE) { print "