Skip to content
Open
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
41 changes: 41 additions & 0 deletions tests/Integration/test_monitor_request_output_wiring.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

Comment on lines +1 to +9
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

This PR is titled/described as adding “Pest v1” infrastructure, but this file is a standalone PHP script (no Pest/PHPUnit usage) and there’s no runner wiring in the repo CI to execute it. Either align the PR description/title to what’s being added, or add the actual Pest-based harness + CI/composer invocation so these checks run.

Copilot uses AI. Check for mistakes.
$checks = array(
__DIR__ . '/../../monitor_controller.php' => array(
"html_escape(get_request_var('downhosts'))",
"html_escape(get_request_var('mute'))",
"html_escape(get_request_var('tree'))",
"html_escape(get_request_var('site'))",
"html_escape(get_request_var('template'))",
"html_escape(get_request_var('size'))",
"html_escape(get_request_var('trim'))",
),
__DIR__ . '/../../monitor_render.php' => array(
"rawurlencode(get_request_var('rfilter'))",
),
);
Comment on lines +10 to +23
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

These checks are implemented as exact-string source scans (strpos on hard-coded snippets), which is very brittle to formatting/refactors and can miss equivalent safe implementations. Also, the expected patterns (e.g. html_escape(get_request_var(...)) / rawurlencode(...)) do not currently exist in monitor_controller.php and monitor_render.php, so this test will fail if executed. Consider moving these assertions into the PR that introduces the hardening, and/or switch to a token/AST-based check (token_get_all) or an integration test that inspects actual rendered output.

Copilot uses AI. Check for mistakes.

foreach ($checks as $path => $patterns) {
$contents = file_get_contents($path);

if ($contents === false) {
fwrite(STDERR, "Unable to read {$path}\n");
exit(1);
}

foreach ($patterns as $pattern) {
if (strpos($contents, $pattern) === false) {
fwrite(STDERR, "Missing expected output hardening: {$pattern}\n");
exit(1);
}
}
}

print "OK\n";
40 changes: 40 additions & 0 deletions tests/e2e/test_monitor_no_raw_request_reuse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

Comment on lines +1 to +9
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

This test is labeled “e2e”, but it doesn’t execute the application end-to-end; it performs a static source-code string scan. Consider renaming/reclassifying it (e.g., “static”/“lint”/“security”) to avoid misleading test categorization.

Copilot uses AI. Check for mistakes.
$checks = array(
__DIR__ . '/../../monitor_controller.php' => array(
"get_request_var('downhosts') . '\"><input id=\"mute\" type=\"hidden\" value=\"' . get_request_var('mute')",
"get_request_var('tree') . '\"></td>'",
"get_request_var('site') . '\"></td>'",
"get_request_var('template') . '\"></td>'",
"get_request_var('size') . '\"></td>'",
"get_request_var('trim') . '\"></td>'",
),
Comment on lines +10 to +18
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

Several “raw request reuse” patterns include escaped quotes (e.g. id="mute" and '">'), but the actual source uses unescaped quotes (id="mute", '">'). As a result, these patterns won’t match and the test will incorrectly pass even when raw get_request_var(...) output remains in hidden inputs. Update the patterns to match the real source text or use a less fragile approach (e.g., tokenization/regex that ignores quoting style).

Copilot uses AI. Check for mistakes.
__DIR__ . '/../../monitor_render.php' => array(
"monitor.php?rfilter=' . get_request_var('rfilter')",
),
);

foreach ($checks as $path => $patterns) {
$contents = file_get_contents($path);

if ($contents === false) {
fwrite(STDERR, "Unable to read {$path}\n");
exit(1);
}

foreach ($patterns as $pattern) {
if (strpos($contents, $pattern) !== false) {
fwrite(STDERR, "Raw request reuse remains: {$pattern}\n");
exit(1);
}
}
}

print "OK\n";
19 changes: 19 additions & 0 deletions tests/unit/test_request_output_escaping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

$payload = "\" autofocus onfocus=\"alert(1)";
$escaped = htmlspecialchars($payload, ENT_QUOTES, 'UTF-8');

if (strpos($escaped, '"') === false && strpos($escaped, '&quot;') !== false) {
print "OK\n";
exit(0);
}

fwrite(STDERR, "Expected request values to be escaped for hidden inputs\n");
exit(1);
Comment on lines +10 to +19
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

This test doesn’t exercise any plugin code or request/hidden-input output; it only asserts PHP’s htmlspecialchars behavior (which will always pass for this payload). The failure message mentions hidden inputs/request values, but nothing in the test checks that—consider rewriting it to assert escaping in the actual rendered HTML (or dropping it if it’s only meant to validate PHP internals).

Suggested change
$payload = "\" autofocus onfocus=\"alert(1)";
$escaped = htmlspecialchars($payload, ENT_QUOTES, 'UTF-8');
if (strpos($escaped, '"') === false && strpos($escaped, '&quot;') !== false) {
print "OK\n";
exit(0);
}
fwrite(STDERR, "Expected request values to be escaped for hidden inputs\n");
exit(1);
fwrite(STDOUT, "SKIP: This file does not exercise plugin rendering; replace with a test that asserts escaping in actual rendered HTML.\n");
exit(0);

Copilot uses AI. Check for mistakes.
Loading