Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/playwright/src/mcp/browser/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@ function allRootPaths(clientInfo: ClientInfo): string[] {


function originOrHostGlob(originOrHost: string) {
// Support wildcard port patterns like "http://localhost:*" or "https://example.com:*"
const wildcardPortMatch = originOrHost.match(/^(https?:\/\/[^/:]+):\*$/);
if (wildcardPortMatch)
return `${wildcardPortMatch[1]}:*/**`;

try {
const url = new URL(originOrHost);
// localhost:1234 will parse as protocol 'localhost:' and 'null' origin.
Expand Down
8 changes: 8 additions & 0 deletions packages/playwright/src/mcp/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,19 @@ export type Config = {
network?: {
/**
* List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
*
* Supported formats:
* - Full origin: `https://example.com:8080` - matches only that origin
* - Wildcard port: `http://localhost:*` - matches any port on localhost with http protocol
*/
allowedOrigins?: string[];

/**
* List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
*
* Supported formats:
* - Full origin: `https://example.com:8080` - matches only that origin
* - Wildcard port: `http://localhost:*` - matches any port on localhost with http protocol
*/
blockedOrigins?: string[];
};
Expand Down
34 changes: 34 additions & 0 deletions tests/mcp/request-blocking.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,37 @@ test('blocked without allowed allows non-explicitly specified origins (origin)',
const result = await fetchPage(client, server.PREFIX + '/ppp');
expect(result).toContain('content:PPP');
});

test('allowed works (wildcard port)', async ({ server, startClient }) => {
server.setContent('/ppp', 'content:PPP', 'text/html');
const { client } = await startClient({
args: ['--allowed-origins', 'http://localhost:*']
});
const result = await fetchPage(client, server.PREFIX + '/ppp');
expect(result).toContain('content:PPP');
});

test('allowed blocks different hostname (wildcard port)', async ({ startClient }) => {
const { client } = await startClient({
args: ['--allowed-origins', 'http://localhost:*'],
});
const result = await fetchPage(client, 'http://example.com/');
expect(result).toMatch(BLOCK_MESSAGE);
});

test('allowed blocks different protocol (wildcard port)', async ({ startClient }) => {
const { client } = await startClient({
args: ['--allowed-origins', 'http://localhost:*'],
});
const result = await fetchPage(client, 'https://localhost:8080/');
expect(result).toMatch(BLOCK_MESSAGE);
});

test('blocked works (wildcard port)', async ({ server, startClient }) => {
server.setContent('/ppp', 'content:PPP', 'text/html');
const { client } = await startClient({
args: ['--blocked-origins', `http://${new URL(server.PREFIX).host.split(':')[0]}:*`]
});
const result = await fetchPage(client, server.PREFIX + '/ppp');
expect(result).toMatch(BLOCK_MESSAGE);
});
Loading