GHSA-cvwp-r2g2-j824 is a high-severity (CVSS 7.5) Information Exposure vulnerability in glances. A fix is available for glances — see the affected versions and patch details below.
Glances has Incomplete Secrets Redaction: /api/v4/args Endpoint Leaks Password Hash and SNMP Credentials
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for GHSA-cvwp-r2g2-j824.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-cvwp-r2g2-j824 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 377,166 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
glancesReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Summary
The GHSA-gh4x fix (commit 5d3de60) addressed unauthenticated configuration secrets exposure on the /api/v4/config endpoints by introducing as_dict_secure() 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 + pbkdf2_hmac), 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 as_dict_secure() when no password is configured:
# glances/outputs/glances_restful_api.py:1168 (FIXED)
args_json = self.config.as_dict() if self.args.password else self.config.as_dict_secure()
However, the _api_args and _api_args_item endpoints were not part of this fix and still return all arguments without any sanitization:
# glances/outputs/glances_restful_api.py:1222-1237
def _api_args(self):
try:
# Get the RAW value of the args dict
# Use vars to convert namespace to dict
args_json = vars(self.args)
except Exception as e:
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get args ({str(e)})")
return GlancesJSONResponse(args_json)
And the item-specific endpoint:
# glances/outputs/glances_restful_api.py:1239-1258
def _api_args_item(self, item: str):
...
args_json = vars(self.args)[item]
return GlancesJSONResponse(args_json)
The self.args namespace contains sensitive fields set during initialization in glances/main.py:
-
password(line 806-819): When--passwordis used, this contains the salt + pbkdf2_hmac hash. An attacker can use this for offline brute-force attacks. -
snmp_community(line 445): Default"public", but may be set to a secret community string for SNMP monitoring. -
snmp_user(line 448): SNMP v3 username, default"private". -
snmp_auth(line 450): SNMP v3 authentication key, default"password"but typically set to a secret value. -
conf_file(line 198): Path to the configuration file, reveals filesystem structure. -
username(line 430/800): The Glances authentication username.
Both endpoints are registered on the authenticated router (line 504-505):
f'{base_path}/args': self._api_args,
f'{base_path}/args/{{item}}': self._api_args_item,
When --password is not set (the default), the router has NO authentication dependency (line 479-480), making these endpoints completely unauthenticated:
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix)
PoC
Scenario 1: No password configured (default deployment)
# 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": "",
# "snmp_community": "public",
# "snmp_user": "private",
# "snmp_auth": "password",
# "username": "glances",
# "conf_file": "/home/user/.config/glances/glances.conf",
# Access specific sensitive argument
curl -s http://localhost:61208/api/4/args/snmp_community
curl -s http://localhost:61208/api/4/args/snmp_auth
Scenario 2: Password configured (authenticated deployment)
# 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$pbkdf2_hmac 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 + pbkdf2_hmac) and perform offline brute-force attacks. The hash uses pbkdf2_hmac 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:
# glances/outputs/glances_restful_api.py
_SENSITIVE_ARGS = frozenset({
'password', 'snmp_community', 'snmp_user', 'snmp_auth',
'conf_file', 'password_prompt', 'username_used',
})
def _api_args(self):
try:
args_json = vars(self.args).copy()
if not self.args.password:
for key in _SENSITIVE_ARGS:
if key in args_json:
args_json[key] = "********"
# Never expose the password hash, even to authenticated users
if 'password' in args_json and args_json['password']:
args_json['password'] = "********"
except Exception as e:
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get args ({str(e)})")
return GlancesJSONResponse(args_json)
def _api_args_item(self, item: str):
if item not in self.args:
raise HTTPException(status.HTTP_400_BAD_REQUEST, f"Unknown argument item {item}")
try:
if item in _SENSITIVE_ARGS:
if not self.args.password:
return GlancesJSONResponse("********")
if item == 'password':
return GlancesJSONResponse("********")
args_json = vars(self.args)[item]
except Exception as e:
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get args item ({str(e)})")
return GlancesJSONResponse(args_json)
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | glances | all versions | 4.5.2pip install --upgrade 'glances==4.5.2' |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for glances, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update glances to 4.5.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-cvwp-r2g2-j824 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-cvwp-r2g2-j824 can be triaged on real exposure rather than presence alone.
Tailored to GHSA-cvwp-r2g2-j824. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-cvwp-r2g2-j824 in your dependencies?
O3 Security finds GHSA-cvwp-r2g2-j824 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.