PT-2026-80640 · Pypi · Glance
Published
2026-08-19
·
Updated
2026-08-19
CVSS v3.1
5.3
Medium
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N |
Summary
Glances provides
as dict secure() explicitly designed for unauthenticated API access, with a docstring stating it returns "a sanitised copy of the configuration dict" where "Sensitive keys in remaining sections are replaced by '********'". However, the implementation only checks KEY names against a regex pattern and never inspects VALUE content. The documented [ip] config section supports public api (URL), public username (login), and public password (password). While public password is correctly masked, both public api (when containing embedded credentials like https://user:pass@host/) and public username are returned in full to unauthenticated users via GET /api/4/config.Affected Versions
Glances latest (Docker:
nicolargo/glances:latest)Root Cause
In
glances/config.py, as dict secure():python
SECURE SENSITIVE KEY RE = re.compile(r"password|token|secret|api key|apikey|ssl keyfile", re.IGNORECASE)
def as dict secure(self):
"""Return a sanitised copy of the configuration dict.
Intended for unauthenticated API access.
- Sensitive keys in remaining sections are replaced by '********'.
"""
sanitized = {}
for section, options in self.as dict().items():
if section in SECURE BLOCKED SECTIONS: continue
sanitized[section] = {
key: "********" if SECURE SENSITIVE KEY RE.search(key) else value
for key, value in options.items()
}
return sanitizedIn
glances/outputs/glances restful api.py:python
# Line 1294
args json = self.config.as dict() if self.args.password else self.config.as dict secure()The
[ip] config section documents: public api (URL), public username (login), public password (password).public password→ matches "password" → masked ✓public api→ no match → returned in full (containsuser:pass@in URL) ✗public username→ no match → returned in full ✗
Impact
- Unauthenticated credential disclosure via
GET /api/4/configorGET /api/4/config/ip as dict secure()exists specifically to protect credentials in no-auth mode but fails to maskpublic usernameand credential-bearing URLs inpublic api
Prerequisites
- Glances in web server mode without
--password(default, no auth) glances.conf[ip]section withpublic apicontaining embedded credentials and/orpublic usernameset
Environment
- Glances latest (Docker:
nicolargo/glances:latest) - Remote Docker lab at
http://10.140.200.102:8080
Reproduction Steps
bash
docker run -d --name glances-test -p 8080:61208 -e GLANCES OPT='-w' nicolargo/glances:latest
sleep 20
docker exec glances-test sed -i 's|public api=https://ipv4.ipleak.net/json/|public api=https://admin:secret123@ipv4.ipleak.net/json/|' /etc/glances/glances.conf
docker exec glances-test sed -i 's|#public username=<myname>|public username=myname|' /etc/glances/glances.conf
docker exec glances-test sed -i 's|#public password=<mysecret>|public password=mysecret|' /etc/glances/glances.conf
docker restart glances-test
sleep 15
curl -s "$TARGET/api/4/config/ip"
# Returns: {"public api": "https://admin:secret123@...", "public username": "myname", "public password": "********"}Evidence
See
C:/Tools/glances-config-leak-evidence.txt.Dedup Check
- GHSA-gfc2-9qmw-w7vh covers CORS but NOT value-level credential leak
- No existing GHSA covers
as dict secure()value-level filtering gap - 13 published GHSA, none covering this issue
Suggested Remediation
Add "username" and "login" to sensitive key pattern, and check values for embedded credentials in URLs.
Disclosure Timeline
- 2026-07-28: Vulnerability discovered and verified via Docker deployment
Reporter
GitHub username: Todor
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Glance