congzhou09/chrome-dev-mcp
highAn MCP server for Chrome runtime debugging
MCP server (purpose undetermined)
207 server.registerTool(
208 'evaluate_js',
209 {
210 description: 'Evaluate javascript in page',
211 inputSchema: z.object({ expression: z.string() }),
212 },
213 async ({ expression }) => {
214 const client = await getClient();
215 if (!client) return NOT_CONNECTED;
216 const result = await client.Runtime.evaluate({ expression, returnByValue: true });
217 return { content: [{ type: 'text', text: JSON.stringify(result.result.value, null, 2) }] };
218 },
219 );// Exploitable if MCP is exposed to untrusted prompts (network_exposed). Even in local-only scenarios, a compromised LLM can abuse this to execute arbitrary JavaScript.
The 'evaluate_js' tool accepts an arbitrary JavaScript expression string and executes it in the context of the connected Chrome page via CDP's Runtime.evaluate. There is no validation, sandboxing, or restriction on what JavaScript can be executed. This allows an attacker (or compromised LLM) to run arbitrary code in the browser, including accessing cookies, localStorage, sessionStorage, making fetch requests to internal or external URLs, modifying page content, and potentially exploiting browser vulnerabilities.
ImpactAn attacker with access to this MCP server (network-exposed) can execute arbitrary JavaScript in the browser context of the connected Chrome instance. This can lead to theft of session tokens, credentials, exfiltration of sensitive data, SSRF attacks via fetch/XHR, defacement, or further exploitation of the browser or internal network.
FixRestrict the 'evaluate_js' tool to a predefined set of safe expressions or implement a sandbox (e.g., using a Web Worker with no DOM access). Alternatively, remove the tool if not essential, or require explicit user confirmation before execution. If the tool is necessary for debugging, document that it provides full code execution capability and ensure the MCP server is not exposed to untrusted networks.
92 const fetchTraceMap = async (scriptUrl: string, sourceMapURL: string): Promise<TraceMap | null> => {
93 try {
94 let raw: string;
95 if (sourceMapURL.startsWith('data:')) {
96 const b64 = sourceMapURL.slice(sourceMapURL.indexOf(',') + 1);
97 raw = Buffer.from(b64, 'base64').toString('utf-8');
98 } else {
99 const mapUrl = new URL(sourceMapURL, scriptUrl).href;
100 const res = await fetch(mapUrl);
101 if (!res.ok) return null;
102 raw = await res.text();
103 }
104 return new TraceMap(raw);
105 } catch {
106 return null;
107 }
108 };// Exploitable when the MCP server is connected to a Chrome instance that can be directed to a malicious page (e.g., via user navigation or compromised site). Network-exposed MCP increases risk.
The fetchTraceMap function constructs a URL by resolving the sourceMapURL against the scriptUrl and then fetches it using the global fetch. The scriptUrl comes from the Debugger.scriptParsed event, which is controlled by the page being debugged. An attacker who can serve a malicious page to the connected Chrome instance can set a sourceMapURL pointing to an internal or external resource, causing the MCP server to make HTTP requests to arbitrary URLs. This is a classic SSRF vulnerability.
ImpactAn attacker can trick the MCP server into making HTTP requests to internal services (e.g., 127.0.0.1, internal cloud metadata endpoints) or external servers, potentially leading to information disclosure, port scanning, or exploitation of internal services.
FixValidate the resolved URL against an allowlist of trusted origins, or disable source map fetching entirely if not needed. Alternatively, use a fetch wrapper that blocks private IP ranges and requires explicit user consent for external requests.
162 server.registerTool(
163 'get_title',
164 {
165 description: 'Get current page title',
166 inputSchema: z.object({}),
167 },
168 async () => {
169 const client = await getClient();
170 if (!client) return NOT_CONNECTED;
171 const result = await client.Runtime.evaluate({ expression: 'document.title', returnByValue: true });
172 return { content: [{ type: 'text', text: String(result.result.value) }] };
173 },
174 );
175
176 server.registerTool(
177 'get_url',
178 ...
179 );
180
181 server.registerTool(
182 'get_html',
183 ...
184 );// Exploitable if MCP is exposed to untrusted prompts. Even local-only, a compromised LLM can read page content.
The tools get_title, get_url, and get_html allow reading the current page's title, URL, and full HTML content without any restriction. While these are typical debugging tools, they expose the entire DOM of the page, which may contain sensitive information such as hidden fields, tokens, or personal data. Combined with evaluate_js, an attacker can exfiltrate any data from the page.
ImpactAn attacker can read the full HTML content of the page being debugged, potentially leaking sensitive data displayed or embedded in the page.
FixConsider limiting the HTML output to a safe subset or requiring user consent before exposing page content. For debugging purposes, document that these tools expose page content.