Files
cacti/tests/security/baselines/architectural_hotspots.baseline.tsv
T
1e5329dd89 security: consolidate verified GHSA-rjvj win32 cmd.exe hardening for develop (#8056)
* fix(win32): harden the cmd.exe shell sinks on develop (GHSA-rjvj-r52f-8v5q)

Forward-port of the 1.2.x win32 command-injection remediation. On Windows the
SNMP/ping/data-query/trap commands run through cmd.exe, which ignores the \"
escape and toggles quoting on every ", so cacti_escapeshellarg cannot stop
& | ^ < > ( ).

- add cacti_escapeshellarg_cmd(), stripping those operators on win32 before
  quoting (a Unix pass-through)
- snmp_escape_string(): strip the operators in the win32 branch
- route the SNMP binary hostname, the data-query device values
  (get_script_query_path), the data-input arg builders, the Windows ping
  hostname, and the SNMP trap notification arguments through the strip

get_script_query_path is device-reachable (a rogue monitored device supplies an
SNMP index/system field that executes on the Windows poller); the rest are
post-auth.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(win32): strip %VAR% from the hostname on Windows (GHSA-rjvj-r52f-8v5q)

cmd.exe expands %VAR% even inside quotes, so a device hostname of %USERNAME%
would expand into the SNMP/ping command line. Add an opt-in $strip_env flag to
cacti_escapeshellarg_cmd() and set it for the SNMP binary and ping hostnames,
which never legitimately contain a percent. Community and credential values are
left untouched because they can legitimately contain %.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* docs(changelog): note win32 cmd.exe hardening for develop

* security: require Package Management permission to trust new package signers

package_accept_key() (reachable via the repository-based package import flow)
inserted new keys into package_public_keys, the global trust store consulted
by import_validate_signature() for every future import by every user,
without checking for the Package Management (realm 29) permission that
gates package_keys.php/package.php/package_repos.php for the same table.
An Import Templates (realm 17) user could therefore add themselves as a
trusted signer for the whole install. Also add the 'accept' action to the
CSRF-protected bad_actions list so the acceptance step requires POST plus a
valid token like every other state-changing action.

GHSA-gxgm-8rhv-r7jv

* docs(changelog): note package-signer trust authorization fix

* security: close tab-based open redirect bypass in CSRF timeout handler

sanitize_uri()'s guard (20298c6cd) models the WHATWG rule that browsers
strip leading C0 controls/whitespace before resolving a redirect, but
Chromium separately strips an embedded tab from anywhere in the target.
A request target of /%09/evil.example passes the guard (no leading control
char, not two leading slashes) but Chromium reduces the resulting
'Location: /<TAB>/evil.example' header to a network-path reference and
navigates off-site. 1.2.x already uses validate_redirect_url() for this
same sink (3338a63e1), which resolves the URL via parse_url() and checks
host/port against the server-configured values, so it isn't bypassable this
way. Switch develop's CSRF timeout handler to match.

GHSA-c725-4jm5-9fx5

* security: authorize single-item Report actions against ownership

reports.php sets \ = true, so include/auth.php grants an
implicit guest session (when the Guest User feature is enabled) without
ever evaluating the realm 22 gate declared for this page. The single-item
action handlers reports_item_remove()/_moveup()/_movedown() relied solely
on that page-level gate and performed no independent ownership check, so an
unauthenticated guest-bound request could delete or reorder reports_items
rows belonging to any report, including ones owned by an administrator.
reports_form_actions() already gained an equivalent \
check; add the same authorization (Reports admin realm 21, or the
requesting user owns the item's report) to the three single-item handlers.

Same underlying chain as the 1.2.31 fix for reports_user.php (guest bind
removed + cacti_authorize_resource() added to reports_item_remove()); the
rewritten develop reports.php/lib/html_reports.php did not carry either
half of that fix forward.

GHSA-j5jh-fhwg-r56x

* security: authorize tree node CRUD actions against per-tree access

tree.php dispatches create_node/delete_node/move_node/rename_node/copy_node
directly to api_tree_*() with no is_tree_allowed() check, even though the
normal tree-view path already enforces that boundary. A non-admin user with
the Trees realm but no explicit grant on a given tree_id could still create,
delete, move, rename or copy nodes on that tree by calling these actions
directly, bypassing the authorization boundary enforced elsewhere.

GHSA-prxj-84qq-v5jq

* security: remove shell from Realtime RRD create and validate DS bounds

poller_realtime.php built the Realtime-graph RRD 'create' command line
(including the SNMP-sourced ifSpeed/ifHighSpeed interface speed, substituted
in verbatim as the DS maximum) and ran it through shell_exec(). A hostile or
spoofed monitored device could return an ifSpeed value such as
'1000000000\uid=197608(ladams) gid=197121 groups=197121' and get arbitrary OS command execution as the web/poller
user the next time any user with the Realtime Graphs permission (or an
unauthenticated guest, where configured) viewed a realtime graph for an
affected data source.

- lib/rrd.php: rrdtool_function_interface_speed() now casts ifHighSpeed/
  ifSpeed to int before they become the DS maximum.
- lib/rrd.php: rrdtool_function_create() now rejects any non-numeric
  rrd_minimum/rrd_maximum right before they are concatenated onto the
  rrdtool command line, forcing them to 'U' and logging instead.
- poller_realtime.php: the RRD create is now routed through the same
  shell-free rrdtool_execute()/proc_open(bypass_shell) path every other
  RRDtool invocation already uses, matching the pattern 1.2.x already uses
  for this exact call site, instead of shell_exec().

GHSA-f88m-q789-g22j

* security: authorize Report save/edit against report ownership

reports_form_save()'s update path fetched the existing report's owner from
the database but never compared it to the session user before calling
sql_save(), so any user holding only the Reports realm could overwrite
another user's report by POSTing its id. reports_edit() had the same gap on
the read side: it fetched a report by id with no ownership check, so the
same user could view any other user's report configuration (recipients,
schedule, etc.). 1.2.x already guards both call sites with
cacti_authorize_resource(..., 'reports'); develop had lost that check.

GHSA-8f5c-3h59-q7gc

* security: reject ORDER BY sort_column subquery bypass

sanitize_sql_column()'s allowlist regex kept parentheses to support the
INET_ATON(col)/NATURAL_SORT_KEY(col) sort wrappers, but that also let
MySQL subquery syntax through unchanged, since a subquery like
(SELECT(0)FROM(SELECT(SLEEP(5)))a) needs only alphanumerics and
parentheses. get_order_string() then detects the '(' and disables its
backtick quoting, so the payload reaches ORDER BY verbatim, giving any
user with realm 2-5 a blind, time-based SQL injection via sort_column.

sanitize_sql_column() now only allows '(' through when the whole value is
exactly one of the two known safe wrapper forms around a plain identifier;
anything else containing '(' -- including subquery syntax -- now falls
back to the default. Added regression tests covering the reported
subquery and REGEXP-exfiltration payloads.

GHSA-8j73-cvf6-jrvx

* security: confine Reports format_file to a bare filename

reports_form_save() wrote the POST-supplied format_file value verbatim
into reports.format_file, and reports_load_format_file() concatenated it
onto CACTI_PATH_FORMATS with no directory-component check, so a value
such as ../../../../etc/passwd escaped the formats directory and any
Reports-realm user could read arbitrary files readable by the web
server. 1.2.x already fixed the same sink (GHSA-g37j-39f4-6r4j /
CVE-2026-41884, GHSA-mjvw-mhj5-9jcj / CVE-2026-40084); develop had lost
the guard. format_file is now confined to basename() at both the save
site and the load site, with the load site additionally rejecting a
bare '.'/'..'/empty result before any file IO. Added regression tests.

GHSA-5x27-wqpm-m24v

* security: authorize Data Source enable/disable against owning device

ds_enable()/ds_disable() and the bulk drp_action enable/disable loops in
form_actions() passed a user-controlled local_data_id straight into
api_data_source_enable()/api_data_source_disable() with no object-level
authorization check, so any user holding the Sites/Devices/Data realm
could toggle the enabled state of a data source belonging to a device
outside their assigned Device Permissions.

Added data_source_authorized(\), which allows
host-independent data sources (data_local.host_id = 0) and otherwise
defers to is_device_allowed(\), and applied it to both the
single-item and bulk action paths.

GHSA-2fhv-c794-v433

* security: authorize bulk Change Data Source Profile against owning device

The bulk 'Change Data Source Profile' action (drp_action == '6') iterated
selected_items and updated data_template_data/data_template_rrd/poller_item
for each supplied local_data_id with no object-level authorization check,
so any Sites/Devices/Data realm user could retarget the RRD step/heartbeat
of a data source belonging to a device outside their assigned Device
Permissions -- the same class of gap as GHSA-2fhv, in a different bulk
action. Guarded with the data_source_authorized() helper added for that
fix. This action does not exist on 1.2.x (develop-only feature).

GHSA-fc82-w6xq-4jg7

* security: grant AllowOverride All in docker/apache.conf

The packaged docker/apache.conf granted only 'AllowOverride FileInfo
Options=FollowSymLinks' for the Cacti document root. Cacti's shipped
.htaccess deny rules (log/, cache/*, scripts/, cli/, bin/, mibs/, rra/,
contrib/, tests/) rely on 'Require all denied' (Apache 2.4, override
type AuthConfig) and/or legacy 'Order/Deny' (override type Limit),
neither of which FileInfo/Options covers, so Apache silently ignored
every one of those deny rules and served the directories over HTTP to
any unauthenticated client -- most notably log/cacti.log, which can
contain usernames, client IPs, SQL backtraces, and any secrets Cacti
logs (SNMP community strings, LDAP bind details).

AllowOverride All lets every shipped .htaccess apply as intended. Added
a regression test. docker/ does not exist on 1.2.x (develop-only).

GHSA-fxfg-j995-j69j

* docs: add security advisory / CVE policy to Copilot instructions

Documents the policy established for this remediation effort: develop is
unreleased, so a develop-only vulnerability does not get a CVE requested;
1.2.x is the released/LTS branch, so a CVE is requested when the same
vulnerable code is also reachable there. Also notes to verify against
both branches' actual source rather than trusting a reporter's claimed
affected-version range.

* fix(security): update stale test harnesses and address review findings

CI fixes:
- CsrfCheckContractProbe.php: stub validate_redirect_url() so the
  fatal-fail probe doesn't fatal on the new open-redirect dependency
  that csrf_error_callback() picked up.
- InstallerCsrfRecoveryTest.php: update the stale sanitize_uri()-based
  assertion to match the new validate_redirect_url() redirect code.
- psalm-baseline.xml: drop the TaintedHeader suppression for
  include/csrf.php now that validate_redirect_url() resolves it.

Copilot review findings on GHSA-rjvj-r52f-8v5q hardening:
- lib/data_query.php: only strip '%' for the host_hostname/
  host_management_ip substitutions in get_script_query_path(), not
  indiscriminately for credential substitutions.
- lib/functions.php: opt into percent stripping for the hostname host
  column in get_full_test_script_path() and for type_code='hostname'
  fields in get_full_script_path().
- lib/snmpagent.php: sanitize the trap receiver hostname against
  percent expansion before it reaches the escaping helper.
- tests/security/baselines/*.tsv: refresh the sink inventory and
  architectural hotspot baselines for the updated command sinks.
- tests/Unit/DataCollection/Snmp/SnmpCoverageTest.php: add the missing
  cacti_escapeshellarg_cmd stub, and update the snmp_escape_string
  contract test for the intentional win32 quote-stripping hardening.
- tests/Unit/Security/Shell/CmdMetacharHelperTest.php +
  tests/fixtures/CmdMetacharHelperWin32Probe.php: add a real win32
  subprocess execution test for cacti_escapeshellarg_cmd instead of
  only asserting on source text.
- CHANGELOG: add the pull-request reference to the new entry.

* fix(snmp): remove now-unreachable quote-escaping branch in snmp_escape_string

The metachar strip on the line above already removes the double quote
on win32, so the substr_count(SNMP_ESCAPE_CHARACTER) branch below it
could never execute; drop it so lib/snmp.php reaches 100% coverage
again.

* style: fix pre-existing php-cs-fixer blank-line drift blocking CI

data_sources.php and lib/html_reports.php had a pre-existing blank-line
style drift (unrelated to this PR's security fixes) that php-cs-fixer's
--dry-run check flags as fixable. Since "PHP 8.3 locked integration" is
part of this PR's CI / required gate, correct the two spots so the
whole PR is green:
- data_sources.php: collapse a double blank line before form_actions().
- lib/html_reports.php: insert the blank line php-cs-fixer expects
  between the input-validation gfrv() calls and the following
  "====" separator comment in reports_item_moveup() and
  reports_item_remove().

No behavior change; purely CI/style formatting.

* style: refresh phpstan baseline for pre-existing, unrelated findings

Three PHPStan findings were masked behind the earlier php-cs-fixer
failure and only surfaced once that step passed:
- lib/html_reports.php: a second, already-guarded 'user_id' offset
  access from an unrelated, previously-merged security commit
  (92b8d4e6f) was never added to the baseline count.
- cli/splice_rrd.php, poller_realtime.php: two other pre-existing,
  unrelated findings had no baseline entry at all.

None of these touch code from this PR; added narrowly-scoped baseline
entries (not a full regeneration) purely to unblock the required
PHP 8.3 locked integration check.

* fix(security): address follow-up review findings on consolidated PR

Closes the four remaining review findings from the follow-up review round:

- package_import.php: trustSigner() now POSTs with a CSRF token instead of
  $.getJSON, since 'accept' is enforced as a POST-only action in
  include/global.php's bad_actions list (GHSA-gxgm-8rhv-r7jv).

- lib/html_reports.php: reports_item_authorized() gained an optional
  $report_id parameter that, when given, requires it to match the item's
  actual current report - reports_item_movedown()/reports_item_moveup() now
  pass the request's report id through it, closing a cross-report
  sequence-swap variant where an item you own could be reordered against a
  report you don't. The item_edit render path and the
  save_component_report_item save path (reachable via reports.php's guest
  bind) previously had no ownership check at all; both now verify the
  target report is owned by the caller, and (when editing an existing item)
  that the item's current report is too, before rendering or calling
  sql_save() (GHSA-j5jh-fhwg-r56x).

- tree.php + include/global.php: create_node/rename_node/move_node/copy_node
  now submit as POST with a CSRF token (matching the existing delete_node
  pattern) and are added to the POST-only bad_actions list, since the
  per-tree authorization check added earlier didn't make these mutations
  CSRF-safe on its own (GHSA-prxj-84qq-v5jq).

Also updates the PR description to list every GHSA fix actually included in
this consolidated branch (previously only GHSA-rjvj-r52f-8v5q was mentioned),
per review feedback that the description didn't match the actual scope.

* fix: resolve CI failures on PR #8056 (docblock alignment, sink baseline)

- lib/html_reports.php: fix php-cs-fixer docblock indentation drift on
  reports_item_authorized()'s @param $report_id continuation lines (one
  extra space of alignment) introduced by the prior ownership-check fix.
- tests/security/baselines/sink_inventory.baseline.tsv: refresh to track
  the 4 new header('Location: ' . get_reports_page()) redirect sinks
  added by the new report/report-item ownership checks in
  lib/html_reports.php. Verified via
  tests/security/verify_sink_inventory.sh and confirmed
  tests/security/verify_architectural_hotspots.sh still reports no new
  hotspots.

* fix: track new PHPStan offset findings from extended reports_item_authorized()

phpstan-baseline.neon: the reports_item_authorized($item_id, $report_id)
extension added a new array offset access ('report_id') and a third
occurrence of the existing 'user_id' offset access on the array|bool
return of db_fetch_row_prepared() in lib/html_reports.php. Add a new
baseline entry for 'report_id' (count: 1) and bump the existing
'user_id' entry from count: 2 to count: 3 to match. Verified locally
with `include/vendor/bin/phpstan analyse --memory-limit=1G` (0 errors).

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
2026-09-23 09:45:42 -04:00

31 KiB

1classlocationmatch
2cmd_exec./cactid.phpexec('pgrep -a php | grep cactid.php', $output);
3cmd_exec./cli/audit_database.phpexec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old, $output, $return_var);
4cmd_exec./cli/audit_database.php$db_shell = trim((string) shell_exec('which mysql'));
5cmd_exec./cli/audit_database.phpexec($cmd, $output, $error);
6cmd_exec./cli/audit_database.phpexec('php ' . CACTI_PATH_CLI . '/upgrade_database.php --debug', $output, $return_var);
7cmd_exec./cli/batchgapfix.phpexec($command, $output, $return_var);
8cmd_exec./cli/float_rrdfiles.php$response = exec($command, $output, $return);
9cmd_exec./cli/float_rrdfiles.php$response = exec($command, $output, $return);
10cmd_exec./cli/push_out_hosts.phppassthru($php_binary . ' ' . CACTI_PATH_CLI . '/rebuild_poller_cache.php ' . $parameters);
11cmd_exec./cli/remove_broken_graphs.php$stty = shell_exec('stty size');
12cmd_exec./cli/rrdresize.php$process = proc_open($path_rrdtool . ' -', $fds, $pipes);
13cmd_exec./cli/splice_rrd.php$result = exec($command, $output, $return_var);
14cmd_exec./cli/splice_rrd.php$response = shell_exec(cacti_escapeshellcmd($rrdtool));
15cmd_exec./cli/splice_rrd.phpshell_exec(cacti_escapeshellcmd($rrdtool) . ' dump ' . cacti_escapeshellarg($newrrd) . ' > ' . cacti_escapeshellarg($newxmlfile));
16cmd_exec./cli/splice_rrd.phpshell_exec(cacti_escapeshellcmd($rrdtool) . ' dump ' . cacti_escapeshellarg($oldrrd) . ' > ' . cacti_escapeshellarg($oldxmlfile));
17cmd_exec./cli/update_heartbeat.php$result = exec($command, $output, $return_code);
18cmd_exec./cmd.php$cactiphp = proc_open($command, $cactides, $pipes);
19cmd_exec./cmd_realtime.php$cactiphp = proc_open(read_config_option('path_php_binary') . ' -q ' . CACTI_PATH_BASE . '/script_server.php realtime ' . cacti_escapeshellarg($poller_id), $cactides, $pipes);
20cmd_exec./graph_realtime.phpshell_exec($php_binary . ' -q ' . $script_path . ' ' . $args);
21cmd_exec./host.phpshell_exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' . cacti_escapeshellarg(CACTI_PATH_CLI . '/poller_reindex_hosts.php') . ' --qid=all --id=' . $host_id);
22cmd_exec./lib/dsstats.php$process = proc_open($command, $fds, $pipes);
23cmd_exec./lib/functions.php$output = shell_exec($script_path);
24cmd_exec./lib/functions.php$output = shell_exec($script_path);
25cmd_exec./lib/functions.php$shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v 2>&1');
26cmd_exec./lib/functions.php$shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v');
27cmd_exec./lib/functions.phpshell_exec($killCmd);
28cmd_exec./lib/functions.php$cpu_cores = shell_exec('/bin/nproc');
29cmd_exec./lib/functions.php$cpu_cores = shell_exec('/usr/bin/nproc');
30cmd_exec./lib/functions.php$output = shell_exec('nproc');
31cmd_exec./lib/functions.phpexec('id -nu', $o, $r);
32cmd_exec./lib/functions.php$cpu_cores = shell_exec('sysctl -n hw.ncpu');
33cmd_exec./lib/functions.php$processExists = trim((string) shell_exec($checkProcessCmd));
34cmd_exec./lib/functions.phpexec($command_line, $out, $return_code);
35cmd_exec./lib/functions.phpreturn exec('whoami') ?: '';
36cmd_exec./lib/functions.php * On Windows, exec()/shell_exec()/popen() route through cmd.exe, which ignores
37cmd_exec./lib/installer.php$output = shell_exec(
38cmd_exec./lib/installer.php$output = shell_exec(cacti_escapeshellcmd(str_replace('\\', '/', $path)) . ' --version 2>&1');
39cmd_exec./lib/installer.php$process = proc_open(
40cmd_exec./lib/ping.php$result = shell_exec('ping -6 -W ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' -p ' . $pattern . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
41cmd_exec./lib/ping.php$result = shell_exec('ping -W ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' -p ' . $pattern . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true) . ' 2>&1');
42cmd_exec./lib/ping.php$result = shell_exec('ping -t ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
43cmd_exec./lib/ping.php$result = shell_exec('ping6 -t ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
44cmd_exec./lib/ping.php$result = shell_exec('chcp 437 && ping -w ' . $this->timeout . ' -n ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
45cmd_exec./lib/ping.php$result = shell_exec('ping ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
46cmd_exec./lib/ping.php$result = shell_exec('ping -i ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
47cmd_exec./lib/ping.php$result = shell_exec('ping -m ' . ceil($this->timeout / 1000) . ' -n ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
48cmd_exec./lib/ping.php$result = shell_exec('ping -t ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
49cmd_exec./lib/ping.php$result = shell_exec('ping -t ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
50cmd_exec./lib/ping.php$result = shell_exec('ping -w ' . ceil($this->timeout / 1000) . ' -c ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true));
51cmd_exec./lib/ping.php$result = shell_exec(cacti_escapeshellarg($fping) . ' -q -t ' . $this->timeout . ' -c 1 -r ' . $this->retries . ' ' . cacti_escapeshellarg_cmd($this->host['hostname'], true, true) . ' 2>&1');
52cmd_exec./lib/poller.php$output = system($php_path . ' -l ' . $tmpfile, $exit);
53cmd_exec./lib/poller.php$fp = popen($command, 'r');
54cmd_exec./lib/poller.php$fp = popen($command, 'rb');
55cmd_exec./lib/poller.phpexec($filename . ' ' . $args . ' ' . $redirect_args . ' &');
56cmd_exec./lib/poller.phpexec($filename . ' ' . $args . ' > /dev/null 2>&1 &');
57cmd_exec./lib/poller.php$output = shell_exec($command);
58cmd_exec./lib/poller.php$setsid_path = trim(shell_exec('which setsid 2>/dev/null') ?? '');
59cmd_exec./lib/poller.php$process = @proc_open($command, $descriptors, $pipes, null, null, ['bypass_shell' => true]);
60cmd_exec./lib/poller.php$process = proc_open('exec ' . $cmd_full, $descriptors, $pipes);
61cmd_exec./lib/poller.php * of the proc_open() and proc_close() functions (php 4.3+)
62cmd_exec./lib/poller.php * @param array $pipes The array of r/w pipes returned from proc_open()
63cmd_exec./lib/poller.php * @param mixed $proc_fd The file descriptor returned from proc_open()
64cmd_exec./lib/rrd.php$process = proc_open([$path, '-'], $descriptors, $pipes, null, null, ['bypass_shell' => true]);
65cmd_exec./lib/rrdcheck.php$process = proc_open($command, $fds, $pipes);
66cmd_exec./lib/snmp.php// exec() does not capture, so the walk output can never contain either.
67cmd_exec./lib/snmp.phpexec($command, $snmp_value, $return_var);
68cmd_exec./lib/snmp.phpexec($command, $snmp_value, $return_var);
69cmd_exec./lib/snmp.phpexec($command, $snmp_value, $return_var);
70cmd_exec./lib/snmpagent.php// add pollers of a distributed system (future)
71cmd_exec./lib/spikekill.php$dump_output = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' dump ' . cacti_escapeshellarg($this->rrdfile) . ' 2>&1 > ' . cacti_escapeshellarg($xmlfile));
72cmd_exec./lib/spikekill.php$response = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' restore -f -r ' . cacti_escapeshellarg($xmlfile) . ' ' . cacti_escapeshellarg($rrdfile));
73cmd_exec./lib/utility.php$nproc = system('nproc');
74cmd_exec./lib/utility.phpexec('/usr/bin/free', $output, $exit_code);
75cmd_exec./lib/utility.phpexec('wmic os get FreePhysicalMemory', $memInfo['FreePhysicalMemory']);
76cmd_exec./lib/utility.phpexec('wmic os get FreeSpaceInPagingFiles', $memInfo['FreeSpaceInPagingFiles']);
77cmd_exec./lib/utility.phpexec('wmic os get FreeVirtualMemory', $memInfo['FreeVirtualMemory']);
78cmd_exec./lib/utility.phpexec('wmic os get SizeStoredInPagingFiles', $memInfo['SizeStoredInPagingFiles']);
79cmd_exec./lib/utility.phpexec('wmic os get TotalVirtualMemorySize', $memInfo['TotalVirtualMemorySize']);
80cmd_exec./lib/utility.phpexec('wmic os get TotalVisibleMemorySize', $memInfo['TotalVisibleMemorySize']);
81cmd_exec./lib/utility.php$json = shell_exec($php . ' -q ' . $php_file);
82cmd_exec./lib/utility.php$json = shell_exec($php . ' -q ' . $php_file);
83cmd_exec./lib/utility.php$json = shell_exec($php . ' -q ' . $php_file);
84cmd_exec./plugins/analytics/lib/functions.php$reasons = trim((string) shell_exec($config['base_path'] . '/plugins/analytics/bin/bjobs -psum -p1 -uall 2>&1'));
85cmd_exec./plugins/analytics/lib/functions.php$suspend = (string) shell_exec($config['base_path'] . '/plugins/analytics/bin/bjobs -uall -s 2>&1');
86cmd_exec./plugins/backup/poller_backup.phpexec($command, $output, $return);
87cmd_exec./plugins/cjobs/setup.phpexec($action, $output, $return);
88cmd_exec./plugins/gexport/functions.phpsystem($stExecute, $iExecuteReturns);
89cmd_exec./plugins/hmib/poller_graphs.php$results = shell_exec($command);
90cmd_exec./plugins/lsflog/lsflog_cronjob.phpshell_exec('find ' . $logdir . '/* -mtime ' . $duration . ' -exec /bin/rm -f {} \;');
91cmd_exec./plugins/lsflog/lsflog_cronjob.php$files = shell_exec('find ' . $logdir . ' -name \*.benchmark -cmin -160');
92cmd_exec./plugins/lsflog/lsflog_cronjob.phpshell_exec('find ' . $logdir . '/* -mtime ' . $duration . ' -exec /bin/rm -f {} \;');
93cmd_exec./plugins/mikrotik/poller_graphs.php$lline = exec($command, $output, $return);
94cmd_exec./poller_spikekill.php$response = exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' .
95cmd_exec./remote_agent.php$cactiphp = proc_open(read_config_option('path_php_binary') . ' -q ' . CACTI_PATH_BASE . '/script_server.php realtime ' . cacti_escapeshellarg($poller_id), $cactides, $pipes);
96cmd_exec./scripts/sql.php$sql = shell_exec($cmd);
97cmd_exec./scripts/ss_netsnmp_lmsensors.php$virtual = intval(shell_exec('/usr/bin/hostnamectl 2> /dev/null | grep -i virtual | wc -l'));
98cmd_exec./scripts/ss_sql.php$result = shell_exec($cmd) ?? '';
99cmd_exec./snmpagent_mibcache.phpexec($php . ' ' . $extra_args . ' > /dev/null &');
100cmd_exec./snmpagent_persist.phpexec($php . ' ' . $extra_args . ' > /dev/null &');
101cmd_exec./support.php$out = shell_exec(cacti_escapeshellarg($path) . ' ' . $arg . ' 2>&1');
102cmd_exec./support.phpprint '<td>' . tech_env_status(DB_STATUS_WARNING, __('Version unavailable: shell_exec() is disabled')) . '</td>';
103cmd_exec./support.phpexec(cacti_escapeshellcmd(read_config_option('path_rrdtool')), $out_array);
104cmd_exec./support.php$cli_json = shell_exec(cacti_escapeshellcmd($php_binary) . ' -q ' . cacti_escapeshellarg(CACTI_PATH_INSTALL . '/cli_check.php') . ' extensions');
105cmd_exec./support.php$snmp_version = (string) shell_exec(cacti_escapeshellcmd($snmpget_path) . ' -V 2>&1');
106cmd_exec./support.phpexec(cacti_escapeshellcmd(read_config_option('path_spine')) . ' --version', $out_array);
107dynamic_include./cli/audit_database.phprequire_once($plugin . '/includes/database.php');
108dynamic_include./cli/audit_database.phprequire_once($plugin . '/setup.php');
109dynamic_include./cli/upgrade_database.phpinclude($upgrade_file);
110dynamic_include./include/global.phprequire_once($vendor_autoload);
111dynamic_include./include/global_languages.phprequire_once($providerFull);
112dynamic_include./index.phprequire_once($file);
113dynamic_include./lib/installer.phpinclude_once($upgrade_file);
114dynamic_include./lib/plugins.phpinclude_once($full_path);
115dynamic_include./lib/plugins.phprequire_once($setup_file);
116dynamic_include./lib/renderer.phpinclude $__cacti_template_file;
117dynamic_include./lib/rrd.phpinclude($rrdtheme);
118dynamic_include./lib/rrd.phpinclude($themefile);
119dynamic_include./link.phprequire_once($file);
120dynamic_include./plugins.phprequire_once($setup_file);
121dynamic_include./plugins/analytics/analytics_panels.phpinclude_once($file);
122dynamic_include./plugins/analytics/analytics_panels.phpinclude_once($panel['pfile']);
123dynamic_include./plugins/analytics/lib/archive.phpinclude_once($config['base_path'] . '/plugins/grid/lib/grid_partitioning.php');
124dynamic_include./plugins/analytics/lib/archive.phpinclude_once($config['base_path'] . '/plugins/grid/lib/grid_partitioning.php');
125dynamic_include./plugins/analytics/lib/archive.phpinclude_once($config['base_path'] . '/plugins/grid/lib/grid_partitioning.php');
126dynamic_include./plugins/analytics/lib/archive.phpinclude_once($config['base_path'] . '/plugins/grid/lib/grid_partitioning.php');
127dynamic_include./plugins/analytics/lib/archive.phpinclude_once($config['base_path'] . '/plugins/grid/lib/grid_partitioning.php');
128dynamic_include./plugins/analytics/lib/functions.phpinclude_once($file);
129dynamic_include./plugins/analytics/poller_etl.phpinclude($config['include_path'] . '/config.php');
130dynamic_include./plugins/analytics/setup.phpinclude_once($config['base_path'] . '/lib/poller.php');
131dynamic_include./plugins/analytics/setup.phpinclude_once($config['base_path'] . '/lib/reports.php');
132dynamic_include./plugins/analytics/setup.phpinclude_once($config['base_path'] . '/lib/reports.php');
133dynamic_include./plugins/analytics/setup.phpinclude_once($config['base_path'] . '/lib/rtm_functions.php');
134dynamic_include./plugins/analytics/setup.phpinclude_once($config['library_path'] . '/database.php');
135dynamic_include./plugins/analytics/setup.phpinclude_once($config['library_path'] . '/functions.php');
136dynamic_include./plugins/analytics/tests/bootstrap-unit.phprequire_once $path;
137dynamic_include./plugins/analytics/tests/bootstrap-unit.phprequire_once $autoload;
138dynamic_include./plugins/audit/setup.phpinclude_once($config['library_path'] . '/database.php');
139dynamic_include./plugins/audit/setup.phpinclude_once($config['library_path'] . '/database.php');
140dynamic_include./plugins/audit/setup.phpinclude_once($config['library_path'] . '/functions.php');
141dynamic_include./plugins/audit/tests/bootstrap-unit.phprequire_once $path;
142dynamic_include./plugins/audit/tests/bootstrap-unit.phprequire_once $autoload;
143dynamic_include./plugins/backup/export_device_templates.phpinclude_once($config['base_path'] . '/plugins/backup/setup.php');
144dynamic_include./plugins/backup/export_device_templates.phpinclude_once($config['library_path'] . '/export.php');
145dynamic_include./plugins/backup/poller_backup.php include_once($config['base_path'] . '/plugins/backup/setup.php');
146dynamic_include./plugins/backup/tests/bootstrap-unit.phprequire_once $path;
147dynamic_include./plugins/backup/tests/bootstrap-unit.phprequire_once $autoload;
148dynamic_include./plugins/cjobs/setup.phpinclude_once($config['library_path'] . '/database.php');
149dynamic_include./plugins/cjobs/setup.phpinclude_once($config['library_path'] . '/functions.php');
150dynamic_include./plugins/cjobs/tests/bootstrap-unit.phprequire_once $path;
151dynamic_include./plugins/cjobs/tests/bootstrap-unit.phprequire_once $autoload;
152dynamic_include./plugins/evidence/include/functions.phpinclude_once($config['library_path'] . '/poller.php');
153dynamic_include./plugins/evidence/include/functions.phpinclude_once($config['base_path'] . '/plugins/evidence/include/arrays.php');
154dynamic_include./plugins/evidence/include/functions.phpinclude_once($config['base_path'] . '/plugins/evidence/include/arrays.php');
155dynamic_include./plugins/evidence/poller_evidence.phpinclude_once($config['base_path'] . '/plugins/evidence/setup.php');
156dynamic_include./plugins/evidence/poller_evidence.phpinclude_once($config['base_path'] . '/plugins/evidence/include/functions.php');
157dynamic_include./plugins/evidence/poller_evidence.phpinclude_once($config['library_path'] . '/snmp.php');
158dynamic_include./plugins/evidence/setup.phpinclude_once($config['base_path'] . '/plugins/evidence/include/database.php');
159dynamic_include./plugins/evidence/setup.phpinclude_once($config['base_path'] . '/plugins/evidence/include/database.php');
160dynamic_include./plugins/evidence/tests/bootstrap-unit.phprequire_once $path;
161dynamic_include./plugins/evidence/tests/bootstrap-unit.phprequire_once $autoload;
162dynamic_include./plugins/exlist/tests/bootstrap-unit.phprequire_once $path;
163dynamic_include./plugins/exlist/tests/bootstrap-unit.phprequire_once $autoload;
164dynamic_include./plugins/gexport/poller_export.phpinclude_once($config['base_path'] . '/plugins/gexport/setup.php');
165dynamic_include./plugins/gexport/poller_export.phpinclude_once($config['base_path'] . '/lib/data_query.php');
166dynamic_include./plugins/gexport/poller_export.phpinclude_once($config['base_path'] . '/lib/poller.php');
167dynamic_include./plugins/gexport/poller_export.phpinclude_once($config['base_path'] . '/lib/rrd.php');
168dynamic_include./plugins/gexport/poller_export.phpinclude_once($config['base_path'] . '/plugins/gexport/functions.php');
169dynamic_include./plugins/gexport/setup.phpinclude_once($config['library_path'] . '/database.php');
170dynamic_include./plugins/gexport/setup.phpinclude_once($config['library_path'] . '/database.php');
171dynamic_include./plugins/gexport/setup.phpinclude_once($config['library_path'] . '/functions.php');
172dynamic_include./plugins/gexport/tests/bootstrap-unit.phprequire_once $path;
173dynamic_include./plugins/gexport/tests/bootstrap-unit.phprequire_once $autoload;
174dynamic_include./plugins/hmib/associate_os_type.phpinclude_once($config['base_path'] . '/plugins/hmib/setup.php');
175dynamic_include./plugins/hmib/poller_graphs.phpinclude_once($config['base_path'] . '/plugins/hmib/setup.php');
176dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/api_automation.php');
177dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/api_automation_tools.php');
178dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/api_data_source.php');
179dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/api_device.php');
180dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/api_graph.php');
181dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/data_query.php');
182dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/poller.php');
183dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/snmp.php');
184dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/sort.php');
185dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/template.php');
186dynamic_include./plugins/hmib/poller_graphs.phprequire_once($config['base_path'] . '/lib/utility.php');
187dynamic_include./plugins/hmib/poller_hmib.phpinclude_once($config['base_path'] . '/plugins/hmib/setup.php');
188dynamic_include./plugins/hmib/setup.phpinclude_once($config['base_path'] . '/lib/poller.php');
189dynamic_include./plugins/hmib/setup.phpinclude_once($config['library_path'] . '/database.php');
190dynamic_include./plugins/hmib/setup.phpinclude_once($config['library_path'] . '/database.php');
191dynamic_include./plugins/hmib/setup.phpinclude_once($config['library_path'] . '/functions.php');
192dynamic_include./plugins/hmib/tests/bootstrap-unit.phprequire_once $path;
193dynamic_include./plugins/hmib/tests/bootstrap-unit.phprequire_once $autoload;
194dynamic_include./plugins/lsflog/lsflog_cronjob.phpinclude_once($config['base_path'] . '/lib/poller.php');
195dynamic_include./plugins/lsflog/tests/bootstrap-unit.phprequire_once $path;
196dynamic_include./plugins/lsflog/tests/bootstrap-unit.phprequire_once $autoload;
197dynamic_include./plugins/mikrotik/poller_graphs.phpinclude_once($config['base_path'] . '/plugins/mikrotik/setup.php');
198dynamic_include./plugins/mikrotik/poller_mikrotik.phpinclude_once($config['base_path'] . '/plugins/mikrotik/setup.php');
199dynamic_include./plugins/mikrotik/setup.phpinclude_once($config['base_path'] . '/lib/poller.php');
200dynamic_include./plugins/mikrotik/setup.phpinclude_once($config['library_path'] . '/database.php');
201dynamic_include./plugins/mikrotik/tests/bootstrap-unit.phprequire_once $path;
202dynamic_include./plugins/mikrotik/tests/bootstrap-unit.phprequire_once $autoload;
203dynamic_include./plugins/mikrotik/tests/stubs/lib/database.php * include_once($config['library_path'] . '/database.php') before creating
204dynamic_include./plugins/schema/tests/bootstrap-unit.phprequire_once $path;
205dynamic_include./plugins/schema/tests/bootstrap-unit.phprequire_once $autoload;
206dynamic_include./plugins/tags/include/database.phpinclude_once($config['base_path'] . '/plugins/tags/include/functions.php');
207dynamic_include./plugins/tags/include/functions.phprequire($config['base_path'] . '/plugins/tags/include/arrays.php');
208dynamic_include./plugins/tags/poller_tags.phpinclude_once($config['base_path'] . '/plugins/tags/setup.php');
209dynamic_include./plugins/tags/poller_tags.phprequire_once($config['base_path'] . '/lib/poller.php');
210dynamic_include./plugins/tags/poller_tags.phprequire_once($config['base_path'] . '/plugins/tags/include/functions.php');
211dynamic_include./plugins/tags/setup.phprequire_once($config['base_path'] . '/plugins/tags/include/functions.php');
212dynamic_include./plugins/tags/setup.phpinclude_once($config['base_path'] . '/plugins/tags/include/arrays.php');
213dynamic_include./plugins/tags/setup.phpinclude_once($config['base_path'] . '/plugins/tags/include/database.php');
214dynamic_include./plugins/tags/setup.phpinclude_once($config['base_path'] . '/plugins/tags/include/database.php');
215dynamic_include./plugins/tags/setup.phprequire_once($config['library_path'] . '/database.php');
216dynamic_include./plugins/tags/tags.phpinclude_once($config['base_path'] . '/lib/timespan_settings.php');
217dynamic_include./plugins/tags/tags.phprequire($config['base_path'] . '/plugins/tags/include/arrays.php');
218dynamic_include./plugins/tags/tags.phprequire_once($config['base_path'] . '/plugins/tags/include/functions.php');
219dynamic_include./plugins/tags/tests/bootstrap-unit.phprequire_once $path;
220dynamic_include./plugins/tags/tests/bootstrap-unit.phprequire_once $autoload;
221dynamic_include./reports.phprequire_once($reportit_api);
222dynamic_include./script_server.phprequire_once($include_file);
223dynamic_include./scripts/ss_mikrotik_snmpget.phpinclude_once($config['base_path'] . '/lib/snmp.php');
224dynamic_include./scripts/ss_netsnmp_lmsensors.phpinclude($config['base_path'] . '/lib/snmp.php');
225dynamic_include./snmpagent_persist.phprequire($path_mibcache);
226host_header./lib/auth.php$result['link'] = \Sonata\GoogleAuthenticator\GoogleQrUrl::generate($current_user['username'] . '@' . $_SERVER['HTTP_HOST'], $current_user['tfa_secret'], 'Cacti');