PT-2026-25819 · Pypi · Glance
Published
2026-03-16
·
Updated
2026-03-16
·
CVE-2026-32632
CVSS v3.1
5.9
| Vector | AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N |
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:
# 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:
# 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:
# 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:
# 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:
- The attacker serves JavaScript from
.https://attacker.example - The victim visits that page while a Glances instance is reachable on the victim network.
- The attacker's DNS for
is rebound from the attacker's server to the Glances IP address.attacker.example - The victim browser now sends same-origin requests to
, but those requests are delivered to Glances.https://attacker.example - Because the Glances REST/WebUI app does not validate the
header or enforce an allowed-host policy, it serves the response.Host - 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
appFastAPI(...) - no
or equivalent host validation is appliedTrustedHostMiddleware - 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:
# 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: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:
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
header does not match an explicit allowlistHost - do not rely on
bind semantics as an access-control boundary0.0.0.0 - document that reverse-proxy deployments must set a strict host allowlist
References
glances/outputs/glances mcp.pyglances/outputs/glances restful api.pyglances/main.py
Fix
Origin Validation Error
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Glance