CVE-2026-32609: Glances has Incomplete Secrets Redaction: /api/v4/args Endpoint Leaks Password Hash and SNMP Credentials
Summary
The GHSA-gh4x fix (commit 5d3de60) addressed unauthenticated configuration secrets exposure on the /api/v4/config endpoints by introducing asdictsecure() redaction. However, the /api/v4/args and /api/v4/args/{item} endpoints were not addressed by this fix. These endpoints return the complete command-line arguments namespace via vars(self.args), which includes the password hash (salt + pbkdf2hmac), SNMP community strings, SNMP authentication keys, and the configuration file path. When Glances runs without --password (the default), these endpoints are accessible without any authentication.
Details
The secrets exposure fix (GHSA-gh4x, commit 5d3de60) modified three config-related endpoints to use asdictsecure() when no password is configured:
python glances/outputs/glancesrestfulapi.py:1168 (FIXED) argsjson = self.config.asdict() if self.args.password else self.config.asdictsecure()
However, the apiargs and apiargsitem endpoints were not part of this fix and still return all arguments without any sanitization:
python glances/outputs/glancesrestfulapi.py:1222-1237 def apiargs(self): try: # Get the RAW value of the args dict # Use vars to convert namespace to dict argsjson = vars(self.args) except Exception as e: raise HTTPException(status.HTTP404NOTFOUND, f"Cannot get args ({str(e)})")
return GlancesJSONResponse(argsjson)
And the item-specific endpoint:
python glances/outputs/glancesrestfulapi.py:1239-1258 def apiargsitem(self, item: str): ... argsjson = vars(self.args)[item] return GlancesJSONResponse(argsjson)
The self.args namespace contains sensitive fields set during initialization in glances/main.py:
1. password (line 806-819): When --password is used, this contains the salt + pbkdf2hmac hash. An attacker can use this for offline brute-force attacks.
2. snmpcommunity (line 445): Default "public", but may be set to a secret community string for SNMP monitoring.
3. snmpuser (line 448): SNMP v3 username, default "private".
4. snmpauth (line 450): SNMP v3 authentication key, default "password" but typically set to a secret value.
5. conffile (line 198): Path to the configuration file, reveals filesystem structure.
6. username (line 430/800): The Glances authentication username.
Both endpoints are registered on the authenticated router (line 504-505): python f'{basepath}/args': self.apiargs, f'{basepath}/args/{{item}}': self.apiargsitem,
When --password is not set (the default), the router has NO authentication dependency (line 479-480), making these endpoints completely unauthenticated: python if self.args.password: router = APIRouter(prefix=self.urlprefix, dependencies=[Depends(self.authentication)]) else: router = APIRouter(prefix=self.urlprefix)
PoC
Scenario 1: No password configured (default deployment)
bash Start Glances in web server mode (default, no password) glances -w
Access all command line arguments without authentication curl -s http://localhost:61208/api/4/args | python -m json.tool
Expected output includes sensitive fields: "password": "", "snmpcommunity": "public", "snmpuser": "private", "snmpauth": "password", "username": "glances", "conffile": "/home/user/.config/glances/glances.conf",
Access specific sensitive argument curl -s http://localhost:61208/api/4/args/snmpcommunity curl -s http://localhost:61208/api/4/args/snmpauth
Scenario 2: Password configured (authenticated deployment)
bash Start Glances with password authentication glances -w --password --username admin
Authenticate and access args (password hash exposed to authenticated users) curl -s -u admin:mypassword http://localhost:61208/api/4/args/password Returns the salt$pbkdf2hmac hash which enables offline brute-force
Impact
- Unauthenticated network reconnaissance: When Glances runs without --password (the common default for internal/trusted networks), anyone who can reach the web server can enumerate SNMP credentials, usernames, file paths, and all runtime configuration.
- Offline password cracking: When authentication is enabled, an authenticated user can retrieve the password hash (salt + pbkdf2hmac) and perform offline brute-force attacks. The hash uses pbkdf2hmac with SHA-256 and 100,000 iterations (see glances/password.py:45), which provides some protection but is still crackable with modern hardware.
- Lateral movement: Exposed SNMP community strings and v3 authentication keys can be used to access other network devices monitored by the Glances instance.
- Supply chain for CORS attack: Combined with the default CORS misconfiguration (finding 001), these secrets can be stolen cross-origin by a malicious website.
Recommended Fix
Apply the same redaction pattern used for the /api/v4/config endpoints:
python glances/outputs/glancesrestfulapi.py
SENSITIVEARGS = frozenset({ 'password', 'snmpcommunity', 'snmpuser', 'snmpauth', 'conffile', 'passwordprompt', 'usernameused', })
def apiargs(self): try: argsjson = vars(self.args).copy() if not self.args.password: for key in SENSITIVEARGS: if key in argsjson: argsjson[key] = "" # Never expose the password hash, even to authenticated users if 'password' in argsjson and argsjson['password']: argsjson['password'] = "" except Exception as e: raise HTTPException(status.HTTP404NOTFOUND, f"Cannot get args ({str(e)})") return GlancesJSONResponse(argsjson)
def apiargsitem(self, item: str): if item not in self.args: raise HTTPException(status.HTTP400BADREQUEST, f"Unknown argument item {item}") try: if item in SENSITIVEARGS: if not self.args.password: return GlancesJSONResponse("") if item == 'password': return GlancesJSONResponse("") argsjson = vars(self.args)[item] except Exception as e: raise HTTPException(status.HTTP404NOTFOUND, f"Cannot get args item ({str(e)})") return GlancesJSONResponse(argsjson)
Other sources
Glances is an open-source system cross-platform monitoring tool. The GHSA-gh4x fix (commit 5d3de60) addressed unauthenticated configuration secrets exposure on the /api/v4/config endpoints by introducing asdictsecure() redaction. However, the /api/v4/args and /api/v4/args/{item} endpoints were not addressed by this fix. These endpoints return the complete command-line arguments namespace via vars(self.args), which includes the password hash (salt + pbkdf2hmac), SNMP community strings, SNMP authentication keys, and the configuration file path. When Glances runs without --password (the default), these endpoints are accessible without any authentication. Version 4.5.2 provides a more complete fix.
— MITRE
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-32609?
CVE-2026-32609 is categorized as a high severity vulnerability due to the exposure of sensitive data, including password hashes and SNMP credentials.
How do I fix CVE-2026-32609?
To fix CVE-2026-32609, update Glances to version 4.5.2 or later where the vulnerability has been addressed.
What is exposed in CVE-2026-32609?
CVE-2026-32609 exposes password hashes and SNMP credentials through the /api/v4/args endpoint.
Who is affected by CVE-2026-32609?
Users of the Glances software versions prior to 4.5.2 are affected by CVE-2026-32609.
Is CVE-2026-32609 an authenticated or unauthenticated vulnerability?
CVE-2026-32609 allows for the exposure of sensitive data without authentication, making it a critical concern.