Summary
The ha-mcp OAuth consent form renders user-controlled parameters via Python f-strings with no HTML escaping. An attacker who can reach the OAuth endpoint and convince the server operator to follow a crafted authorization URL could execute JavaScript in the operator's browser. This affects only users running the beta OAuth mode (ha-mcp-oauth), which is not part of the standard setup and requires explicit configuration.
Details
Unescaped f-string rendering
consent_form.py builds HTML using Python f-strings. No call to html.escape() exists anywhere in the file. The following values are rendered unescaped:
client_name/client_id, in HTML element context (lines 299, 303)client_id,redirect_uri,state, in HTML attribute context (lines 310–312), where a"character breaks out ofvalue=""error_message,error,error_description, in error display paths (lines 36–40, 496–497)
An attacker can register a client with a malicious client_name via the /register (DCR) endpoint, which accepts client_name without sanitization. If the server operator then visits a crafted authorization URL for that client, the payload executes in their browser.
Open Dynamic Client Registration
DCR is enabled by default with no initial access token required. This is intentional: Claude.ai and ChatGPT must self-register on first use, which is the standard MCP OAuth flow (RFC 7591). Requiring a pre-shared token would break those integrations. Registration alone grants no access, authorization requires an explicit action by the server operator.
Upgrade to 7.0.0
Impact
Affected configuration: OAuth mode only (ha-mcp-oauth, requires MCP_BASE_URL). This mode is in beta and is not included in the main setup documentation. The vast majority of ha-mcp users run stdio mode, which is not affected.
Attack requirements:
- The attacker can reach the ha-mcp OAuth endpoint (it binds to
0.0.0.0in HTTP mode) - The attacker registers a malicious client via
/register - The attacker convinces the server operator, the person who set up ha-mcp, to follow a crafted authorization URL for an unrecognized application
Step 3 is a meaningful social engineering bar: the consent form displays the (unfamiliar) application name, and the operator has no legitimate reason to authorize an OAuth client they didn't initiate through Claude.ai or ChatGPT. Normal usage involves being redirected to the consent form from one of those platforms, not from an external link.
If exploited, a JavaScript payload could exfiltrate data entered into the consent form, including the Home Assistant Long-Lived Access Token.
Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.
CVE-2026-32112 has a CVSS score of 6.8 (Medium). The vector is network-reachable, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (7.0.0); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-32112? CVE-2026-32112 is a medium-severity cross-site scripting (XSS) vulnerability in ha-mcp (pip), affecting versions < 7.0.0. It is fixed in 7.0.0. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
- How severe is CVE-2026-32112? CVE-2026-32112 has a CVSS score of 6.8 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of ha-mcp are affected by CVE-2026-32112? ha-mcp (pip) versions < 7.0.0 is affected.
- Is there a fix for CVE-2026-32112? Yes. CVE-2026-32112 is fixed in 7.0.0. Upgrade to this version or later.
- Is CVE-2026-32112 exploitable, and should I be worried? Whether CVE-2026-32112 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-32112 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-32112? Upgrade
ha-mcpto 7.0.0 or later.