security: harden shell command execution against injection (1.2.x backport)#6902
Merged
TheWitness merged 6 commits intoCacti:1.2.xfrom Mar 29, 2026
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Security hardening backport to reduce command-injection risk across Cacti’s shell invocations (poller/realtime, SQL scripts, ping, and file ownership operations), with new unit tests intended to guard the changes.
Changes:
- Escapes/normalizes shell command arguments (e.g., host_id/local_graph_id, script paths, hostnames) before
shell_exec(). - Replaces a
chownshell invocation with PHP-nativechown()/chgrp()in Boost. - Adds new unit test files covering the shell-hardening changes.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/ss_sql.php |
Refactors mysqladmin command construction for escaping (currently broken due to missing execution/undefined variable). |
scripts/sql.php |
Refactors mysqladmin invocation to use shell_exec() + escaping (currently broken and changes output semantics). |
graph_realtime.php |
Casts graph ID to int and escapes PHP binary/script path before invoking realtime poller. |
host.php |
Casts host_id to int and escapes PHP binary/script path for reindex shell invocation. |
lib/ping.php |
Applies cacti_escapeshellarg() to hostname in ping shell calls. |
lib/boost.php |
Replaces shell chown with chown()/chgrp() (but currently doesn’t check return values); also introduces a docblock typo. |
lib/rrd.php |
Introduces multiple spelling regressions in comments. |
tests/Unit/GraphRealtimeShellTest.php |
Adds Pest-style tests for realtime graph shell hardening (assertions don’t match current implementation). |
tests/Unit/SqlScriptsTest.php |
Adds Pest-style tests for SQL scripts hardening (assertions don’t match current implementation; Pest not present in repo deps). |
Comments suppressed due to low confidence (1)
scripts/ss_sql.php:46
- In ss_sql(), $cmd is built but never executed and $result is used before it is assigned. This currently makes all the preg_replace() calls operate on an undefined variable and will always return 'U' (and may emit notices). Execute the command (e.g., via shell_exec) and initialize $result from its output (handling null) before applying preg_replace().
$cmd = 'mysqladmin --host=' . cacti_escapeshellarg($database_hostname) . ' --user=' . cacti_escapeshellarg($database_username);
if ($database_password != '') {
$cmd .= ' --password=' . cacti_escapeshellarg($database_password);
}
$result = preg_replace('/: /', ':', $result);
$result = preg_replace('/ /', ' ', $result);
Contributor
Author
|
Security advisories addressed:
Verification: PHP lint clean, PHPStan level 5 clean, 108 Pest tests pass. |
…kport) - Apply cacti_escapeshellarg() to hostname in lib/ping.php - Escape PHP binary and script path in graph_realtime.php shell_exec - Escape host_id in host_reindex shell command - Replace shell_exec chown with PHP chown()/chgrp() with return value checks in rrd.php and boost.php - Escape db_dump_data exec arguments in lib/rrd.php - Use cacti_escapeshellarg() in scripts/sql.php and scripts/ss_sql.php - Parse mysqladmin output in PHP instead of piping through awk - Add unit tests for graph_realtime shell and SQL script hardening Addresses GHSA-xq98-376r-hv9j (Critical) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
40d6fcb to
d21bdae
Compare
TheWitness
requested changes
Mar 28, 2026
Add shell_exec to execute command for database operations.
bmfmancini
approved these changes
Mar 29, 2026
TheWitness
approved these changes
Mar 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
cacti_escapeshellarg()to hostname inlib/ping.phpgraph_realtime.phpshell_execshell_execchown with PHPchown()/chgrp()inrrd.phpandboost.phpdb_dump_dataexec arguments inlib/rrd.phpcacti_escapeshellarg()inscripts/sql.phpandscripts/ss_sql.phpSecurity
Addresses GHSA-xq98-376r-hv9j (Critical) - Command Injection in RRDtool execution
Test plan
vendor/bin/pest tests/Unit/GraphRealtimeShellTest.php tests/Unit/SqlScriptsTest.php