Skip to content

fix: apply URL filters to resource loading#2225

Open
mturac wants to merge 2 commits into
ChromeDevTools:mainfrom
mturac:fix/issue-2218-resource-url-patterns
Open

fix: apply URL filters to resource loading#2225
mturac wants to merge 2 commits into
ChromeDevTools:mainfrom
mturac:fix/issue-2218-resource-url-patterns

Conversation

@mturac

@mturac mturac commented Jun 17, 2026

Copy link
Copy Markdown

Fixes #2218.

McpContext.loadResource() already validated file: resources through workspace roots, but direct http:/https: resource fetches did not apply the configured URL filters. This threads the existing blocked/allowed URL patterns into the context and checks them before fetching remote resources.

Regression coverage uses the local test server to verify blocked URLs are rejected, allowed URLs still load, and an empty allowlist does not accidentally deny all resource loads.

How I tested:

  • npm run test tests/McpContext.test.ts
  • npm run test tests/network_blocking.test.ts
  • npm run check-format

I also tried npm run test; the build completed, but the full suite failed locally in timing-sensitive unrelated tests (telemetry.test.ts waiting for server_start, and shutdown.test.ts stdin-EOF shutdown budget).

@OrKoN OrKoN requested review from nattallius and nroscino June 18, 2026 08:12
@mturac mturac force-pushed the fix/issue-2218-resource-url-patterns branch from fac5343 to a611c2c Compare June 19, 2026 11:11

@nattallius nattallius left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks you for contribution! Looks good for me mostly.

Сan you also add validation of both patterns in src/bin/chrome-devtools-mcp-cli-options.ts

blockedUrlPattern: {
    type: 'array',
    describe:
      'Restricts network access by blocking specified URL patterns (uses https://urlpattern.spec.whatwg.org/). Silently detaches from targets with blocked URLs upon connection, and blocks runtime requests (including navigations and subresources). Accepts an array of patterns.',
    conflicts: ['allowedUrlPattern'],
    coerce: (patterns: unknown[] | undefined) => {
      if (!patterns) {
        return undefined;
      }
      for (const pattern of patterns) {
        new URLPattern(String(pattern));
      }
      return patterns.map(String);
    },
  }

Comment thread src/McpContext.ts
performanceCrux: boolean;
// Whether allowlist/blocklist is configured.
hasNetworkBlockOrAllowlist?: boolean;
// URL patterns to block for direct resource loads.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now as we pass options into context, we don't need to pass hasNetworkBlockOrAllowlist and we can calculate and assign it in the context constructor ourself. Can you please remove it from McpContextOptions

Comment thread tests/McpContext.test.ts
});
});

it('http protocol respects the network blocklist', async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('http protocol respects the network blocklist', async () => {
it('should block remote resources matching the blocklist', async () => {

Comment thread tests/McpContext.test.ts
);
});

it('http protocol respects the network allowlist', async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('http protocol respects the network allowlist', async () => {
it('should only load remote resources matching the allowlist', async () => {

Comment thread tests/McpContext.test.ts
);
});

it('http protocol ignores an empty network allowlist', async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('http protocol ignores an empty network allowlist', async () => {
it('should allow all remote resources if the allowlist is empty', async () => {

@Lightning00Blade Lightning00Blade self-requested a review June 22, 2026 11:21
describe:
'Restricts network access by allowing only specified URL patterns (uses https://urlpattern.spec.whatwg.org/). Requires Chrome 149+. Silently detaches from targets with unallowed URLs upon connection, and blocks runtime requests (including navigations and subresources). Accepts an array of patterns.',
conflicts: ['blockedUrlPattern'],
coerce: (patterns: unknown[] | undefined) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's extract this is a helper function - verifyUrlPatterns

Comment thread src/McpContext.ts
Comment on lines +134 to +137
this.#allowlist =
options.allowlist && options.allowlist.length > 0
? options.allowlist.map(pattern => new URLPattern(pattern))
: undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.#allowlist =
options.allowlist && options.allowlist.length > 0
? options.allowlist.map(pattern => new URLPattern(pattern))
: undefined;
this.#allowlist = options.allowlist?.map(pattern => new URLPattern(pattern));

Comment thread src/McpContext.ts
#options: McpContextOptions;
#heapSnapshotManager = new HeapSnapshotManager();
#roots: Root[] | undefined = undefined;
#blocklist: URLPattern[];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have the same pattern of

Suggested change
#blocklist: URLPattern[];
#blocklist: URLPattern[] | undefined;

And check for existence in #validateNetworkResource

Comment thread src/McpContext.ts
}

#validateNetworkResource(url: URL): void {
const urlString = url.href;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for this variable we can pass the url directly to the pattern.test

Comment thread tests/McpContext.test.ts
import {getMockRequest, html, withMcpContext} from './utils.js';

describe('McpContext', () => {
const server = serverHooks();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this under describe('loadResource', () => {

Comment thread tests/cli.test.ts

it('rejects invalid blocked-url-pattern values', async () => {
assert.throws(() =>
cliOptions.blockedUrlPattern.coerce(['https://[invalid']),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not test the function directly but use the parseArguments to validate the parsing. Similar to how it's done for other tests.

@mturac mturac force-pushed the fix/issue-2218-resource-url-patterns branch from ace7cb8 to 574cd29 Compare June 22, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Apply url allowlist / blocklist to source maps being loaded

3 participants