Skip to content

Commit e9d6a2d

Browse files
hardening: move to argument array pattern for shell execution (backport to 1.2.x)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
1 parent d16af49 commit e9d6a2d

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

lib/poller.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,15 @@ function exec_poll_php($command, $using_proc_function, $pipes, $proc_fd) {
130130
* @return (void)
131131
*/
132132
function exec_background($filename, $args = '', $redirect_args = '') {
133-
global $config, $debug;
133+
global $debug;
134+
135+
if (is_array($args)) {
136+
$args = implode(' ', array_map('cacti_escapeshellarg', $args));
137+
}
138+
139+
if (is_array($redirect_args)) {
140+
$redirect_args = implode(' ', $redirect_args);
141+
}
134142

135143
cacti_log("DEBUG: About to Spawn a Remote Process [CMD: $filename, ARGS: $args]", true, 'POLLER', ($debug ? POLLER_VERBOSITY_NONE:POLLER_VERBOSITY_DEBUG));
136144

lib/rrd.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ function rrdtool_execute() {
255255
function __rrd_execute($command_line, $log_to_stdout, $output_flag, $rrdtool_pipe = false, $logopt = 'WEBLOG') {
256256
global $config;
257257

258+
if (is_array($command_line)) {
259+
$command_line = implode(' ', array_map('cacti_escapeshellarg', $command_line));
260+
}
261+
258262
static $last_command;
259263

260264
if (!is_numeric($output_flag)) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/*
3+
+-------------------------------------------------------------------------+
4+
| Copyright (C) 2004-2026 The Cacti Group |
5+
| |
6+
| This program is free software; you can redistribute it and/or |
7+
| modify it under the terms of the GNU General Public License |
8+
| as published by the Free Software Foundation; either version 2 |
9+
| of the License, or (at your option) any later version. |
10+
+-------------------------------------------------------------------------+
11+
| Cacti: The Complete RRDtool-based Graphing Solution |
12+
+-------------------------------------------------------------------------+
13+
*/
14+
15+
require_once dirname(__DIR__) . '/Helpers/CactiStubs.php';
16+
17+
// Mock cacti_escapeshellarg if it doesn't exist in testing env
18+
if (!function_exists('cacti_escapeshellarg')) {
19+
function cacti_escapeshellarg($arg) {
20+
return "'" . str_replace("'", "'\\''", $arg) . "'";
21+
}
22+
}
23+
24+
test('__rrd_execute correctly handles array of arguments', function () {
25+
$args = array('graph', '-', '--start', '12345; id');
26+
27+
// Simulated logic from __rrd_execute
28+
$command_line = implode(' ', array_map('cacti_escapeshellarg', $args));
29+
30+
expect($command_line)->toBe("'graph' '-' '--start' '12345; id'");
31+
});
32+
33+
test('exec_background correctly handles array of arguments', function () {
34+
$args = array('--poller=1', '--network=192.168.1.0/24; id');
35+
36+
// Simulated logic from exec_background
37+
$args_string = implode(' ', array_map('cacti_escapeshellarg', $args));
38+
39+
expect($args_string)->toBe("'--poller=1' '--network=192.168.1.0/24; id'");
40+
});

0 commit comments

Comments
 (0)