From ac182ccb7545f5f987f642215d2ae41fbe7e1456 Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Mon, 16 Feb 2026 15:38:23 +0800 Subject: [PATCH] fix: restrict URL schemes in page navigation to http/https The new_page and navigate_page tools pass user-provided URLs directly to page.goto() without validating the URL scheme. This allows navigating to potentially dangerous schemes like file://, chrome://, or data: URLs. Add URL scheme validation that restricts navigation to http:, https:, and about: schemes. --- src/tools/pages.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 60fc8f3b6..73d470856 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -11,6 +11,24 @@ import {zod} from '../third_party/index.js'; import {ToolCategory} from './categories.js'; import {CLOSE_PAGE_ERROR, defineTool, timeoutSchema} from './ToolDefinition.js'; +const ALLOWED_URL_SCHEMES = ['http:', 'https:', 'about:']; + +function validateUrlScheme(url: string): void { + let parsed: URL; + try { + parsed = new URL(url); + } catch { + // If it can't be parsed as a URL, let the browser handle it + // (e.g. relative paths or malformed input) + return; + } + if (!ALLOWED_URL_SCHEMES.includes(parsed.protocol)) { + throw new Error( + `URL scheme "${parsed.protocol}" is not allowed. Allowed schemes: ${ALLOWED_URL_SCHEMES.join(', ')}`, + ); + } +} + export const listPages = defineTool({ name: 'list_pages', description: `Get a list of pages open in the browser.`, @@ -96,6 +114,7 @@ export const newPage = defineTool({ ...timeoutSchema, }, handler: async (request, response, context) => { + validateUrlScheme(request.params.url); const page = await context.newPage(request.params.background); await context.waitForEventsAfterAction( @@ -193,6 +212,7 @@ export const navigatePage = defineTool({ 'A URL is required for navigation of type=url.', ); } + validateUrlScheme(request.params.url); try { await page.goto(request.params.url, options); response.appendResponseLine(