GHSA-73wf-9vmv-5pv9: OS Command Injection
Summary CVE-2026-32608 ("Command Injection via Process Names in Action Command Templates") was fixed (commit 5680a5d) by adding sanitizemustachedict, which replaces the shell operators &&, |, >>, > with spaces in the values rendered into action command templates.
The sanitizer only processes top-level string values (if isinstance(v, str)). Attacker-controlled nested values — most notably a process's cmdline, which Glances exposes as a list and which is fully attacker-controlled via argv — are passed through unsanitized. Because the Mustache renderer (chevron) does not HTML-escape the pipe character |, a | embedded in such a nested value survives into the rendered command and is then interpreted by securepopen (which still interprets &&/|/> by default, allowoperators=True), re-introducing the exact command injection the CVE was meant to close.
Details The fix (glances/actions.py): python SHELLOPERATORS = ('&&', '|', '>>', '>') # line 25
def sanitizemustachedict(mustachedict): # line 28 ... for k, v in mustachedict.items(): if isinstance(v, str): # line 40 <-- ONLY top-level strings for op in SHELLOPERATORS: v = v.replace(op, ' ') safe[k] = v else: safe[k] = v # nested list/dict passed VERBATIM return safe Render + sink (glances/actions.py:104-111): python safedict = sanitizemustachedict(mustachedict) cmdfull = chevron.render(cmd, safedict) # chevron does NOT escape '|' ... ret = securepopen(cmdfull) # securepopen(cmd, allowoperators=True) securepopen (glances/secure.py:17, default allowoperators=True) splits the command by &&, then securepopen interprets | (pipe to a new process) and > (write output to a file). A surviving | therefore launches an attacker-named second process.
The attacker-controlled nested value — cmdline. The action mustachedict is the per-item plugin stat (glances/plugins/plugin/model.py:931 mustachedict = item, then :943 self.actions.run(..., mustachedict=mustachedict)). For the processlist plugin, each item contains cmdline, a list of the process arguments, set by the attacker simply by launching a process with chosen argv. The sanitizer's isinstance(v, str) test skips the list, so its elements reach chevron.render unmodified.
Why the operator survives render. chevron/Mustache HTML-escapes & < > " ' for {{var}} (so > and && are neutralized) but does not escape |. A pipe in the (unsanitized) nested value therefore reaches securepopen intact and is interpreted.
Parent-fix attribution (verified against the real diff of commit 5680a5d / CVE-2026-32608): that fix added exactly SHELLOPERATORS, sanitizemustachedict, and the sanitizemustachedict(mustachedict) call — and the sanitizer's docstring explicitly claims to neutralize "user-controllable data (process names, container names, mount points, etc.)". It does so only for top-level strings; the list/dict case (else: safe[k] = v) was left unsanitized. This is therefore a genuine incomplete-fix gap, not a re-report of the patched (top-level string) vector.
Proof of Concept Lab-only, harmless (touches a marker file; non-destructive). Runs the real glances chain (sanitizemustachedict → chevron.render → securepopen) — see poc/glancesnestedmustachepoc.py.
Attacker process argv (the only attacker input): cmdline = ['x', '|touch /tmp/glancespocmarker', '#']. Admin action template (renders the offending process's cmdline): echo ALERT {{#cmdline}}{{.}} {{/cmdline}}.
Observed (confirmed on develop HEAD 92156d0/4.5.6 and verified code-identical on v4.5.5): cmdline after sanitizer : ['x', '|touch /tmp/glancespocmarker', '#'] <- pipe survives cmdfull -> securepopen : 'echo ALERT x |touch /tmp/glancespocmarker # ' [VULNERABLE] marker created -> /tmp/glancespocmarker (command injection executed) Replacing touch /tmp/... with any command yields arbitrary execution in the Glances process context.
Preconditions (stated honestly) - A configured alert action whose command template renders a nested stat field (e.g. the process cmdline via a {{#cmdline}}…{{/cmdline}} section). Templates that render only flat string fields ({{name}}, {{value}}, {{username}}, {{mntpoint}}) are not affected — those values are sanitized. - Glances running with privilege to enumerate the attacker's process (typically root in server/agent monitoring deployments) → privilege boundary crossed (S:C).
Impact A local unprivileged user gains OS command execution in the Glances security context (commonly root) — the same impact and threat model as the parent CVE-2026-32608, re-enabled for any action template that renders a nested stat field. The injection is reliable once the (admin-set) template references such a field.
Suggested fix - Sanitize recursively — apply the operator stripping to strings inside lists and dicts, not only top-level str values. - And/or build the templated action as an argument list and run it via securepopen(..., allowoperators=False) / shell=False without operator interpretation. - And/or also strip the pipe | (and treat all SHELLOPERATORS) on every rendered string regardless of nesting; do not rely on Mustache HTML-escaping (it does not escape |).
Credit Ta Duc Thien
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/glancesto a version that resolves this vulnerability.Fixed in 4.5.6 - Upgrade
Upgrade
Glancesto a version that resolves this vulnerability.Fixed in 4.5.6 - Configuration
Update the Mustache dictionary sanitizer in glances/actions.py to apply the _SHELL_OPERATORS replacement (&&, |, >>, >) to nested values as well. The current behavior only sanitizes top-level strings (if isinstance(v, str)) and leaves list/dict elements (e.g., cmdline as a list) unsanitized; modify it so nested strings inside lists/dicts are also sanitized before chevron.render and secure_popen.
Glances (actions templating / sanitize for mustache_dict) mustache_dict sanitization for shell operators = Recursively sanitize strings inside nested lists/dicts (apply _SHELL_OPERATORS replacement to list/dict elements, not only top-level values)
Event History
Frequently Asked Questions
What is the severity of GHSA-73wf-9vmv-5pv9?
The severity of GHSA-73wf-9vmv-5pv9 is rated high with a score of 8.8.
How do I fix GHSA-73wf-9vmv-5pv9?
To fix GHSA-73wf-9vmv-5pv9, upgrade to version 4.5.6 or later of Glances.
What is the impact of GHSA-73wf-9vmv-5pv9?
GHSA-73wf-9vmv-5pv9 allows for OS command injection through improperly sanitized command templates.
What software is affected by GHSA-73wf-9vmv-5pv9?
GHSA-73wf-9vmv-5pv9 affects the Glances software package.
What is the primary vulnerability type of GHSA-73wf-9vmv-5pv9?
The primary vulnerability type of GHSA-73wf-9vmv-5pv9 is OS Command Injection.