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).
Affected file: glances/outdated.py, method Outdated._load_cache(), line 121
Direct URL (commit 04579778e733d705898a169e049dc84772c852da):
# 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__():
# 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...
1.3.11.3.21.3.31.3.41.3.51.3.61.3.71.41.4.11.4.1.1+124 more4.5.5Exploitability
AV:LAC:LPR:LUI:NScope
S:UImpact
C:HI:HA:HCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H