security: consolidate verified GHSA fixes for develop (batch 3) + CHANGELOG CVE reconciliation (#8141)

* security: consolidate verified GHSA fixes for develop (batch 3)

Develop counterparts of the 1.2.x fixes in #8138, each re-verified against
develop HEAD.

- GHSA-77pr-g949-4v5f: spikekill.php also requires is_graph_allowed() on the
  target graph, not just the Spike Kill realm.
- GHSA-w3qw-762w-6g9v: the include/global.php GET action guard fails closed on
  an array-form action[] before the scalar denylist comparison.
- GHSA-xhpr-w454-cc9w: update_poller_cache() casts the stored output_type to
  int before interpolation.
- GHSA-j3px-vw6r-g25x: graphs_new.php escapes stored snmp_index via db_qstr()
  in the data-query IN() pivot.
- GHSA-h745-3r76-g253: graphs_new.php escapes the data-query and field names in
  the XML parse error messages (__ -> __esc).

GHSA-297h-95ff-r767 does not apply on develop: the clog log-file selector
renders through the drop_array filter framework, which escapes.

tests/Unit/Security/ConsolidatedBatch3Test.php adds source-scanning regression
guards. CHANGELOG (1.3.0-dev) updated; php -l, the security baselines, and
check-changelog.py all pass.

* chore: lead 1.3.0-dev security CHANGELOG entries with the GHSA id

Normalize the 1.3.0-dev -security entries to the approved
"-security: GHSA-xxxx [CVE-xxxx] Description" form, moving the advisory id to
the front. CVE tokens are omitted because none of these advisories have a CVE
issued yet (verified via the repository security-advisories API). Covers the
five batch-3 entries plus the pre-existing entries that still used the trailing
(GHSA-xxxx) form.

* chore: use the -security#GHSA-xxxx: form for the 1.3.0-dev CHANGELOG entries

Correct the batch-3 and reconciled 1.3.0-dev -security entries to the approved
"-security#GHSA-xxxx: CVE-yyyy Description" form (GHSA id in the prefix). No CVE
tokens are added because none of these advisories have a CVE issued yet
(verified via the repository security-advisories API).

* test: split batch-3 security guards into vulnerability-class files; reconcile CHANGELOG

- Move the ConsolidatedBatch3Test.php guards into the matching Auth, Csrf,
  SqlInjection and Xss folders with behavior-based filenames, and strengthen
  them per review: the GET-guard test asserts the array branch actually returns
  405 and exits; the snmp_index test rejects both raw concatenation branches;
  the parse-error test asserts every name-bearing message uses __esc().
- Append this pull request number to the five new 1.3.0-dev security entries.
- Add issued CVE identifiers to the older -security#GHSA CHANGELOG entries
  (verified via the repository security-advisories API). Entries with no CVE
  yet, entries that already carried a CVE, and non-GHSA lines are unchanged.
This commit is contained in:
TheWitness authored and GitHub committed 2026-10-02 11:03:52 -04:00
1 parent 850778aa5b
commit 0055dd00cc
10 files changed
+216 -58

No files matched your search

+55 -50
View File
@@ -1,20 +1,25 @@
Cacti CHANGELOG
1.3.0-dev
-security: Validate host_id before it is concatenated into the graph_view list and preview filter WHERE clauses (GHSA-r7hc-hrpv-52gf) (#8100) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security: Validate and bind local_graph_id in the aggregate graph item sequence query (GHSA-6mjm-5vwr-3fr2) (#8099) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security: Grant AllowOverride All in docker/apache.conf so shipped .htaccess denies on log/cache/scripts/cli take effect (GHSA-fxfg-j995-j69j)
-security: Authorize the bulk Change Data Source Profile action against the owning device (GHSA-fc82-w6xq-4jg7)
-security: Authorize Data Source enable/disable against the owning device before mutating (GHSA-2fhv-c794-v433)
-security: Confine Reports format_file to a bare filename to close a path traversal/LFI regression (GHSA-5x27-wqpm-m24v)
-security: Reject ORDER BY sort_column subquery payloads that bypassed the GHSA-q9xg-p762-9jm3 fix (GHSA-8j73-cvf6-jrvx)
-security: Authorize Report save/edit against report ownership to close an authenticated IDOR (GHSA-8f5c-3h59-q7gc)
-security: Stop building the Realtime RRD create command through a shell and validate DS bounds are numeric before they reach it (GHSA-f88m-q789-g22j)
-security: Authorize tree node create/delete/move/rename/copy against per-tree access before mutating (GHSA-prxj-84qq-v5jq)
-security: Authorize single-item Report actions (remove/move) against report ownership to close a guest-bind IDOR (GHSA-j5jh-fhwg-r56x)
-security: Use validate_redirect_url() for the CSRF timeout redirect to close a tab-based open redirect bypass (GHSA-c725-4jm5-9fx5)
-security: Require Package Management permission to trust new package signers (GHSA-gxgm-8rhv-r7jv)
-security: Harden cmd.exe shell sinks and strip %VAR% from hostnames on win32 (GHSA-rjvj-r52f-8v5q) (#8056)
-security#GHSA-77pr-g949-4v5f: Authorize the target graph before Spike Kill rewrites its RRD history (#8141)
-security#GHSA-w3qw-762w-6g9v: Reject array-form GET actions that bypass the POST and CSRF guard (#8141)
-security#GHSA-xhpr-w454-cc9w: Cast the stored data-query output_type before building the poller cache query (#8141)
-security#GHSA-j3px-vw6r-g25x: Escape stored snmp_index values in the New Graphs data-query pivot (#8141)
-security#GHSA-h745-3r76-g253: Escape the data-query and field names in the New Graphs parse error messages (#8141)
-security#GHSA-r7hc-hrpv-52gf: Validate host_id before it is concatenated into the graph_view list and preview filter WHERE clauses (#8100) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security#GHSA-6mjm-5vwr-3fr2: Validate and bind local_graph_id in the aggregate graph item sequence query (#8099) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security#GHSA-fxfg-j995-j69j: Grant AllowOverride All in docker/apache.conf so shipped .htaccess denies on log/cache/scripts/cli take effect
-security#GHSA-fc82-w6xq-4jg7: Authorize the bulk Change Data Source Profile action against the owning device
-security#GHSA-2fhv-c794-v433: Authorize Data Source enable/disable against the owning device before mutating
-security#GHSA-5x27-wqpm-m24v: Confine Reports format_file to a bare filename to close a path traversal/LFI regression
-security#GHSA-8j73-cvf6-jrvx: Reject ORDER BY sort_column subquery payloads that bypassed the GHSA-q9xg-p762-9jm3 fix
-security#GHSA-8f5c-3h59-q7gc: Authorize Report save/edit against report ownership to close an authenticated IDOR
-security#GHSA-f88m-q789-g22j: Stop building the Realtime RRD create command through a shell and validate DS bounds are numeric before they reach it
-security#GHSA-prxj-84qq-v5jq: Authorize tree node create/delete/move/rename/copy against per-tree access before mutating
-security#GHSA-j5jh-fhwg-r56x: Authorize single-item Report actions (remove/move) against report ownership to close a guest-bind IDOR
-security#GHSA-c725-4jm5-9fx5: Use validate_redirect_url() for the CSRF timeout redirect to close a tab-based open redirect bypass
-security#GHSA-gxgm-8rhv-r7jv: Require Package Management permission to trust new package signers
-security#GHSA-rjvj-r52f-8v5q: Harden cmd.exe shell sinks and strip %VAR% from hostnames on win32 (#8056)
-security: Reject SHA-1 signatures across every package import path
-security: Escape path_dsstats_log before it reaches the dsstats poller shell redirect
-security: Revoke anonymous access when the guest account is disabled
@@ -490,12 +495,12 @@ Cacti CHANGELOG
-issue#6183: Checkbox is displayed always on in some cases
1.2.29
-security#GHSA-pv2c-97pp-vxwg: Local File Inclusion (LFI) Vulnerability via Poller Standard Error Log Path
-security#GHSA-f9c7-7rc3-574c: SQL Injection vulnerability when using tree rules through Automation API
-security#GHSA-pv2c-97pp-vxwg: CVE-2024-45598 Local File Inclusion (LFI) Vulnerability via Poller Standard Error Log Path
-security#GHSA-f9c7-7rc3-574c: CVE-2025-24368 SQL Injection vulnerability when using tree rules through Automation API
-security#GHSA-vj9g-P7F2-4wqj: SQL Injection vulnerability when view host template
-security#GHSA-fh3x-69rr-qqpp: SQL Injection vulnerability when request automation devices
-security#GHSA-c5j8-jxj3-hh36: Authenticated RCE via multi-line SNMP responses
-security#GHSA-fxrq-fr7h-9rqq: Arbitrary File Creation leading to RCE
-security#GHSA-fh3x-69rr-qqpp: CVE-2024-54145 SQL Injection vulnerability when request automation devices
-security#GHSA-c5j8-jxj3-hh36: CVE-2025-22604 Authenticated RCE via multi-line SNMP responses
-security#GHSA-fxrq-fr7h-9rqq: CVE-2025-24367 Arbitrary File Creation leading to RCE
-issue#5843: Issue with temporary tables with use of microtime
-issue#5847: Presets Time in Cacti 1.2.28 Not Automatically Updating...
-issue#5848: RRDfile Auto Clean not working
@@ -517,10 +522,10 @@ Cacti CHANGELOG
-feature#5933: Only attempt to change the table type and character encoding for built-in Cacti tables
1.2.28
-security#GHSA-49f2-hwx9-qffr: XSS vulnerability when creating external links with the consolenewsection parameter
-security#GHSA-fgc6-g8gc-wcg5: XSS vulnerability when creating external links with the title parameter
-security#GHSA-gxq4-mv8h-6qj4: RCE vulnerability can be executed via Log Poisoning
-security#GHSA-wh9c-v56x-v77c: XSS vulnerability when creating external links with the fileurl parameter
-security#GHSA-49f2-hwx9-qffr: CVE-2024-43365 XSS vulnerability when creating external links with the consolenewsection parameter
-security#GHSA-fgc6-g8gc-wcg5: CVE-2024-43364 XSS vulnerability when creating external links with the title parameter
-security#GHSA-gxq4-mv8h-6qj4: CVE-2024-43363 RCE vulnerability can be executed via Log Poisoning
-security#GHSA-wh9c-v56x-v77c: CVE-2024-43362 XSS vulnerability when creating external links with the fileurl parameter
-issue#5636: When using LDAP authentication the first time, warnings may appear in logs
-issue#5754: When installing, a replication loop for plugin_realms may occur
-issue#5759: When installing, remote poller may attempt to sync with other pollers
@@ -557,15 +562,15 @@ Cacti CHANGELOG
-feature: Improve the performance of the repopulation of the poller cache
1.2.27
-security#GHSA-37x7-mfjv-mm7m: Authentication Bypass when using using older password hashes
-security#GHSA-7cmj-g5qc-pj88: RCE vulnerability when importing packages
-security#GHSA-cx8g-hvq8-p2rv: RCE vulnerability when plugins include files
-security#GHSA-gj3f-p326-gh8r: SQL Injection vulnerability when using tree rules through Automation API
-security#GHSA-grj5-8fcj-34gh: XSS vulnerability when using JavaScript based messaging API
-security#GHSA-jrxg-8wh8-943x: SQL Injection vulnerability when using form templates
-security#GHSA-p4ch-7hjw-6m87: XSS vulnerability when reading tree rules with Automation API
-security#GHSA-rqc8-78cm-85j3: XSS vulnerability when managing data queries
-security#GHSA-vjph-r677-6pcc: SQL Injection vulnerability when retrieving graphs using Automation API
-security#GHSA-37x7-mfjv-mm7m: CVE-2024-34340 Authentication Bypass when using using older password hashes
-security#GHSA-7cmj-g5qc-pj88: CVE-2024-25641 RCE vulnerability when importing packages
-security#GHSA-cx8g-hvq8-p2rv: CVE-2024-31459 RCE vulnerability when plugins include files
-security#GHSA-gj3f-p326-gh8r: CVE-2024-31460 SQL Injection vulnerability when using tree rules through Automation API
-security#GHSA-grj5-8fcj-34gh: CVE-2024-29894 XSS vulnerability when using JavaScript based messaging API
-security#GHSA-jrxg-8wh8-943x: CVE-2024-31458 SQL Injection vulnerability when using form templates
-security#GHSA-p4ch-7hjw-6m87: CVE-2024-31444 XSS vulnerability when reading tree rules with Automation API
-security#GHSA-rqc8-78cm-85j3: CVE-2024-31443 XSS vulnerability when managing data queries
-security#GHSA-vjph-r677-6pcc: CVE-2024-31445 SQL Injection vulnerability when retrieving graphs using Automation API
-issue#5622: Improve PHP 8.3 support
-issue#5628: When importing packages via command line, data source profile could not be selected
-issue#5629: When changing password, returning to previous page does not always work
@@ -637,24 +642,24 @@ Cacti CHANGELOG
-feature#5597: Add OSCX 6x00 templates
1.2.25
-security#GHSA-77rf-774j-6h3p: Protect against Insecure deserialization of filter data
-security#GHSA-gx8c-xvjh-9qh4: Protect against Cross-Site Scripting vulnerability when creating new graphs
-security#GHSA-6r43-q2fw-5wrg: Protect against Unauthenticated SQL Injection when viewing graphs
-security#GHSA-6jhp-mgqg-fhqg: Protect against SQL Injection when saving data with sql_save()
-security#GHSA-g6ff-58cj-x3cp: Protect against Authenticated command injection when using SNMP options
-security#GHSA-q4wh-3f9w-836h: Protect against Authenticated SQL injection vulnerability when managing graphs
-security#GHSA-gj95-7xr8-9p7g: Protect against Authenticated SQL injection vulnerability when managing reports
-security#GHSA-v5w7-hww7-2f22: Protect against SQL Injection when using regular expressions
-security#GHSA-4pjv-rmrp-r59x: Protect against Open redirect in change password functionality
-security#GHSA-rwhh-xxm6-vcrv: Protect against Cross-Site Scripting vulnerability with Device Name when managing Data Sources
-security#GHSA-24w4-4hp2-3j8h: Protect against Cross-Site Scripting vulnerability with Device Name when administrating Reports
-security#GHSA-5hpr-4hhc-8q42: Protect against Cross-Site Scripting vulnerability with Device Name when editing Graphs whilst managing Reports
-security#GHSA-vqcc-5v63-g9q7: Protect against Cross-Site Scripting vulnerability with Device Name when managing Data Sources
-security#GHSA-9fj7-8f2j-2rw2: Protect against Cross-Site Scripting vulnerability with Device Name when debugging data queries
-security#GHSA-6hrc-2cfc-8hm7: Protect against Cross-Site Scripting vulnerability with Data Source Name when managing Graphs
-security#GHSA-hrg9-qqqx-wc4h: Protect against Cross-Site Scripting vulnerability with Data Source Name when debugging Data Queries
-security#GHSA-r8qq-88g3-hmgv: Protect against Cross-Site Scripting vulnerability with Data Source Information when managing Data Sources
-security#GHSA-rf5w-pq3f-9876: Protect against Privilege escalation when Cacti installed using Windows Installer defaults
-security#GHSA-77rf-774j-6h3p: CVE-2023-30534 Protect against Insecure deserialization of filter data
-security#GHSA-gx8c-xvjh-9qh4: CVE-2023-39360 Protect against Cross-Site Scripting vulnerability when creating new graphs
-security#GHSA-6r43-q2fw-5wrg: CVE-2023-39361 Protect against Unauthenticated SQL Injection when viewing graphs
-security#GHSA-6jhp-mgqg-fhqg: CVE-2023-39357 Protect against SQL Injection when saving data with sql_save()
-security#GHSA-g6ff-58cj-x3cp: CVE-2023-39362 Protect against Authenticated command injection when using SNMP options
-security#GHSA-q4wh-3f9w-836h: CVE-2023-39359 Protect against Authenticated SQL injection vulnerability when managing graphs
-security#GHSA-gj95-7xr8-9p7g: CVE-2023-39358 Protect against Authenticated SQL injection vulnerability when managing reports
-security#GHSA-v5w7-hww7-2f22: CVE-2023-39365 Protect against SQL Injection when using regular expressions
-security#GHSA-4pjv-rmrp-r59x: CVE-2023-39364 Protect against Open redirect in change password functionality
-security#GHSA-rwhh-xxm6-vcrv: CVE-2023-39366 Protect against Cross-Site Scripting vulnerability with Device Name when managing Data Sources
-security#GHSA-24w4-4hp2-3j8h: CVE-2023-39510 Protect against Cross-Site Scripting vulnerability with Device Name when administrating Reports
-security#GHSA-5hpr-4hhc-8q42: CVE-2023-39511 Protect against Cross-Site Scripting vulnerability with Device Name when editing Graphs whilst managing Reports
-security#GHSA-vqcc-5v63-g9q7: CVE-2023-39512 Protect against Cross-Site Scripting vulnerability with Device Name when managing Data Sources
-security#GHSA-9fj7-8f2j-2rw2: CVE-2023-39513 Protect against Cross-Site Scripting vulnerability with Device Name when debugging data queries
-security#GHSA-6hrc-2cfc-8hm7: CVE-2023-39514 Protect against Cross-Site Scripting vulnerability with Data Source Name when managing Graphs
-security#GHSA-hrg9-qqqx-wc4h: CVE-2023-39515 Protect against Cross-Site Scripting vulnerability with Data Source Name when debugging Data Queries
-security#GHSA-r8qq-88g3-hmgv: CVE-2023-39516 Protect against Cross-Site Scripting vulnerability with Data Source Information when managing Data Sources
-security#GHSA-rf5w-pq3f-9876: CVE-2023-31132 Protect against Privilege escalation when Cacti installed using Windows Installer defaults
-issue#2959: When rebuilding the Poller Cache from command line, allow it to be multi-threaded
-issue#4045: When searching tree or list views, the URL does not update after changes
-issue#5254: When creating a Data Source Template with a specific snmp port, the port is not always applied
+7 -4
View File
@@ -710,11 +710,11 @@ function graphs() : void {
}
}
} else {
raise_message('xmlfielderr' . $field_name, __('Error Parsing Data Query Resource XML file for Data Query \'%s\' with id \'%s\'. Field Name \'%s\' missing a \'direction\' attribute', $snmp_query['name'], $snmp_query['id'], $field_name), MESSAGE_LEVEL_ERROR);
raise_message('xmlfielderr' . $field_name, __esc('Error Parsing Data Query Resource XML file for Data Query \'%s\' with id \'%s\'. Field Name \'%s\' missing a \'direction\' attribute', $snmp_query['name'], $snmp_query['id'], $field_name), MESSAGE_LEVEL_ERROR);
}
}
} elseif (!$message_raised) {
raise_message('xmlerror', __('Error Parsing Data Query Resource XML file for Data Query \'%s\' with id \'%s\'', $snmp_query['name'], $snmp_query['id']), MESSAGE_LEVEL_ERROR);
raise_message('xmlerror', __esc('Error Parsing Data Query Resource XML file for Data Query \'%s\' with id \'%s\'', $snmp_query['name'], $snmp_query['id']), MESSAGE_LEVEL_ERROR);
$message_raised = true;
}
}
@@ -781,10 +781,13 @@ function graphs() : void {
if (cacti_sizeof($indexes)) {
foreach ($indexes as $index) {
// GHSA-j3px-vw6r-g25x: snmp_index is stored host_snmp_cache
// data; quote and escape it so a crafted index cannot break
// out of this IN() list.
if ($sql_where != '') {
$sql_where .= ", '" . $index['snmp_index'] . "'";
$sql_where .= ', ' . db_qstr($index['snmp_index']);
} else {
$sql_where .= " AND snmp_index IN('" . $index['snmp_index'] . "'";
$sql_where .= ' AND snmp_index IN(' . db_qstr($index['snmp_index']);
}
}
+9
View File
@@ -813,6 +813,15 @@ if ($config['is_web']) {
if (isrv('action')) {
$action = gnrv('action');
// GHSA-w3qw-762w-6g9v: an array-form action[] makes every scalar
// $action == $bad comparison below false, slipping a state-changing
// action past this guard. A real action is never an array here.
if (is_array($action)) {
header('Allow: POST');
http_response_code(405);
exit;
}
// State-changing actions must arrive by POST with a CSRF token. Their
// links use cactiPostAction so the query fields and token are submitted
// in the request body instead of remaining cross-origin GET targets.
+4 -1
View File
@@ -233,7 +233,10 @@ function update_poller_cache(mixed $data_source, bool $commit = false, ?int $pol
$params = [];
if (cacti_sizeof($field) && $field['output_type'] != '') {
$output_type_sql = ' AND sqgr.snmp_query_graph_id = ' . $field['output_type'];
// GHSA-xhpr-w454-cc9w: output_type is a stored snmp_query_graph_id
// interpolated into the query below; cast it so a tampered
// data-query field cannot inject SQL second-hand.
$output_type_sql = ' AND sqgr.snmp_query_graph_id = ' . (int) $field['output_type'];
} else {
$output_type_sql = '';
}
+8 -3
View File
@@ -41,13 +41,18 @@ if (isrv('method')) {
}
}
if (is_realm_allowed(1043)) {
$local_graph_id = gfrv('local_graph_id');
// GHSA-77pr-g949-4v5f: the Spike Kill realm (1043) only grants use of the
// feature, not access to a specific graph. Authorize the target graph too so a
// realm holder cannot destroy the RRD history of a graph they are denied.
if (is_realm_allowed(1043) && is_graph_allowed($local_graph_id)) {
$local_data_ids = db_fetch_assoc_prepared('SELECT DISTINCT data_template_rrd.local_data_id
FROM graph_templates_item
LEFT JOIN data_template_rrd
ON graph_templates_item.task_item_id=data_template_rrd.id
WHERE graph_templates_item.local_graph_id = ?',
[gfrv('local_graph_id')]);
[$local_graph_id]);
$results = '';
@@ -112,7 +117,7 @@ if (is_realm_allowed(1043)) {
}
}
print json_encode(['local_graph_id' => grv('local_graph_id'), 'results' => $results]);
print json_encode(['local_graph_id' => $local_graph_id, 'results' => $results]);
} else {
print __('FATAL: Spike Kill Not Allowed') . PHP_EOL;
}
@@ -0,0 +1,23 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-77pr-g949-4v5f: spikekill.php authorized only the Spike Kill realm
* (1043) and never the target graph, so a realm holder could destroy the RRD
* history of a graph their permissions deny.
*/
$root = dirname(__DIR__, 4);
test('spikekill authorizes the target graph in addition to the Spike Kill realm', function () use ($root) {
$source = file_get_contents($root . '/spikekill.php');
expect($source)->toContain('is_realm_allowed(1043) && is_graph_allowed($local_graph_id)')
->and($source)->not->toContain("if (is_realm_allowed(1043)) {\n\t\$local_data_ids");
});
@@ -0,0 +1,33 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-w3qw-762w-6g9v: an array-form action[] made every scalar $action == $bad
* comparison in the include/global.php GET guard false, slipping a
* state-changing action past it. The array guard must itself fail closed.
*/
$root = dirname(__DIR__, 4);
test('the GET action guard rejects an array action by failing closed before the denylist', function () use ($root) {
$source = file_get_contents($root . '/include/global.php');
$guard = strpos($source, 'if (is_array($action)) {');
$loop = strpos($source, 'foreach ($bad_actions as $bad) {');
expect($guard)->not->toBeFalse()
->and($loop)->not->toBeFalse()
->and($guard)->toBeLessThan($loop);
// the guard body itself must return 405 and terminate, not merely exist
$body = substr($source, $guard, $loop - $guard);
expect($body)->toContain('http_response_code(405)')
->and($body)->toContain('exit;');
});
@@ -0,0 +1,26 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-j3px-vw6r-g25x: snmp_index is stored host_snmp_cache data interpolated
* raw into an IN() list in graphs_new.php. Both the first-item and the
* subsequent-item branches must quote/escape it via db_qstr().
*/
$root = dirname(__DIR__, 4);
test('New Graphs escapes snmp_index in both branches of the IN() pivot', function () use ($root) {
$source = file_get_contents($root . '/graphs_new.php');
expect($source)->toContain("db_qstr(\$index['snmp_index'])")
// first-item branch must not concatenate the raw value
->and($source)->not->toContain("\" AND snmp_index IN('\" . \$index['snmp_index']")
// subsequent-item branch must not concatenate the raw value either
->and($source)->not->toContain("\", '\" . \$index['snmp_index'] . \"'");
});
@@ -0,0 +1,23 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-xhpr-w454-cc9w: output_type is a stored snmp_query_graph_id interpolated
* into a query in update_poller_cache(); it must be cast to int so a tampered
* data-query field cannot inject SQL second-hand.
*/
$root = dirname(__DIR__, 4);
test('update_poller_cache casts the stored output_type to int before interpolation', function () use ($root) {
$source = file_get_contents($root . '/lib/utility.php');
expect($source)->toContain("sqgr.snmp_query_graph_id = ' . (int) \$field['output_type']")
->and($source)->not->toContain("sqgr.snmp_query_graph_id = ' . \$field['output_type']");
});
@@ -0,0 +1,28 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-h745-3r76-g253: the data-query name and field name reached the New
* Graphs XML parse error messages through __() (no escaping). Both
* name-bearing messages (the xmlfielderr branch and the data-query-name
* xmlerror branch) must use __esc(); the id-only xmlerror carries no user
* string and stays on __().
*/
$root = dirname(__DIR__, 4);
test('New Graphs escapes the data-query and field names in every name-bearing parse error', function () use ($root) {
$source = file_get_contents($root . '/graphs_new.php');
// the two name-bearing messages escape; the id-only message does not
expect(substr_count($source, "__esc('Error Parsing Data Query Resource XML file"))->toBe(2)
->and(substr_count($source, "__('Error Parsing Data Query Resource XML file"))->toBe(1)
->and($source)->toContain("raise_message('xmlfielderr' . \$field_name, __esc(")
->and($source)->not->toContain("raise_message('xmlfielderr' . \$field_name, __(");
});