[ ⌘K ]
← BACK TO SEARCH

congzhou09/chrome-dev-mcp

high

An MCP server for Chrome runtime debugging

MCP server (purpose undetermined)

purpose: MCP server (purpose undetermined)threat: network exposed
TypeScript0May 20, 2026May 20, 2026GITHUB
5/20/2026
high1 finding
src/server.ts
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  );
src/index.ts:49src/server.ts:23

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

high1 finding
src/server.ts
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  };
src/server.ts:110-124src/server.ts:92-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.

medium1 finding
src/server.ts
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  );
src/index.ts:49src/server.ts:23

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

network.httpauth.none
65
LLM-based
high findings+50
medium findings+15