Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Changelog
--- develop ---
* security: Move the map region navigation's 'Start Over' and 'Print' buttons from inline `onclick` handlers to delegated jQuery bindings in `js/GPSMaps.js` (via `gpsmapStartOver`/`gpsmapPrint` classes) so the map no longer trips Cacti's Content-Security-Policy script-src-attr directive
* dev: Replace the translation-template CI check that regenerated locales/po/cacti.pot and compared it with a diff-based gate (tests/bin/check-i18n-pot.php) requiring cacti.pot to be updated only when a pull request adds, removes, or modifies an i18n function call
* refactor: Switch every file inclusion from include/include_once to require/require_once for fail-fast consistency (schema already lives in includes/setup/database.php via the plugin table API, so no schema changes were needed)
* dev: Measure CI coverage with xdebug instead of pcov so the plugin's own sources are instrumented (pcov auto-scopes to the Composer root and skipped cacti/plugins/, leaving the patch-coverage gate with nothing to measure)
Expand Down
4 changes: 2 additions & 2 deletions includes/polling/processregion.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,8 @@ function gpsmap_render_region(array $hostArrays, string $subnet, ?GpsmapPollStat

// print out the information we have gathered.
$body .= '<div id="gpstopmenu" style="overflow: auto; width:100%; ">';
$body .= '<div id="gpsnav" style="overflow:auto; float:left; position:relative;"><input type="button" value="' . __esc('Start Over', 'gpsmap') . '" onclick="window.location.reload(true);" />';
$body .= '<input type="button" class="print" alt="" value="' . __esc('Print', 'gpsmap') . '" onclick="window.open(\'print.php\')" />';
$body .= '<div id="gpsnav" style="overflow:auto; float:left; position:relative;"><input type="button" class="gpsmapStartOver" value="' . __esc('Start Over', 'gpsmap') . '" />';
$body .= '<input type="button" class="print gpsmapPrint" alt="" value="' . __esc('Print', 'gpsmap') . '" />';
Comment thread
TheWitness marked this conversation as resolved.
$body .= '</div>';

// six links per column block
Expand Down
14 changes: 14 additions & 0 deletions js/GPSMaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,17 @@ var gpsmap = {
}
}
};

$(function() {
$(document).off('click.gpsmapNav', '.gpsmapStartOver')
.on('click.gpsmapNav', '.gpsmapStartOver', function(event) {
event.preventDefault();
window.location.reload(true);
});

$(document).off('click.gpsmapNav', '.gpsmapPrint')
.on('click.gpsmapNav', '.gpsmapPrint', function(event) {
event.preventDefault();
window.open('print.php');
});
});
39 changes: 39 additions & 0 deletions tests/Integration/RegionMenuCspTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

/*
* Regression coverage for the CSP fix in gpsmap_render_region(): the region
* navigation's "Start Over" and "Print" controls must render as delegated
* jQuery targets (CSS classes) rather than inline onclick handlers that
* Cacti's Content-Security-Policy script-src-attr directive blocks.
*
* Uses expect() (a real PHPUnit assertion) so the test is not flagged risky
* and its line coverage of processregion.php is recorded by the gate.
*/

require_once __DIR__ . '/../../setup.php';
require_once __DIR__ . '/../../class/hosts_class.php';
require_once __DIR__ . '/../../includes/polling/functions.php';
require_once __DIR__ . '/../../includes/polling/processregion.php';
require_once __DIR__ . '/../../includes/dns.php';

it('renders the region navigation controls without inline onclick handlers', function () {
gpsmap_test_use_tmp_root();
$root = gpsmap_test_tmpdir();

// An empty estate still publishes the navigation menu, which is enough to
// exercise the Start Over / Print button markup.
expect(gpsmap_render_region([[], []], '198.51.100'))->toBeTrue();

$menu = file_get_contents($root . '/plugins/gpsmap/XML/198.51.100-top.html');

expect($menu)->toContain('class="gpsmapStartOver"');
expect($menu)->toContain('class="print gpsmapPrint"');
expect($menu)->not->toContain('onclick');
});
Loading