VulnWatch VulnWatch
← Back to dashboard
High github · GHSA-x975-rgx4-5fh4

appium-mcp: Unescaped Locator Data XSS in MCP-UI Resource (createLocatorGeneratorUI)

Published Jun 19, 2026 CVSS 8.2

Unescaped Locator Data XSS in MCP-UI Resource (createLocatorGeneratorUI)

Summary

appium-mcp's createLocatorGeneratorUI function interpolates attacker-controlled element attributes — text, content-desc, resource-id, and locator selector values — directly into an HTML template literal without any HTML or JavaScript context escaping. An attacker who controls the UI of the app under test can inject arbitrary HTML and JavaScript into the MCP UI resource returned by the generate_locators tool. When a victim's MCP client renders this resource, the injected script executes and can invoke arbitrary MCP tools via window.parent.postMessage, leading to unauthorized MCP tool execution such as taking screenshots, reading page source, or any other registered capability.

Details

The vulnerability is a stored/reflected cross-site scripting (XSS) issue in the MCP UI generation pipeline.

Vulnerable sink — src/ui/mcp-ui-utils.ts:730–740:

${element.text ? `Text: ${element.text}` : ''}
${element.contentDesc ? `Content Desc: ${element.contentDesc}` : ''}
${element.resourceId ? `Resource ID: ${element.resourceId}` : ''}
${selector}
Test

None of element.text, element.contentDesc, element.resourceId, selector, or strategy are HTML-escaped before insertion. The onclick attribute additionally embeds selector and strategy into an inline JavaScript string using only a backtick-escape that is insufficient to prevent breakout via HTML event attribute syntax or single-quote injection.

By contrast, createPageSourceInspectorUI at src/ui/mcp-ui-utils.ts:911–916 does apply escaping to the page source, confirming that the protection gap in createLocatorGeneratorUI is an oversight, not a design choice.

Complete data flow (source → sink):

  1. src/tools/test-generation/locators.ts:57getPageSource(driver) reads the page source XML from an active Appium session; the connected app is fully attacker-controlled.
  2. src/tools/test-generation/locators.ts:72 — the raw page source is passed to generateAllElementLocators.
  3. src/locators/source-parsing.ts:108 — XML attribute values undergo only newline replacement (attr.value.replace(/(\n)/gm, '\n')); HTML entities such as < are decoded into raw `

Affected AI Products

mcp server
Get the weekly digest. Every Monday: top AI security stories of the week. Free.