Skip to content

[Bug]: clientCertificates ignores launch-level proxy and proxy.bypass, routing traffic outside the configured proxy #42806

Description

@Abnoz01

Version

1.64.0-next (main @ 07f1a61); code path unchanged since 1.46

Steps to reproduce

When clientCertificates is set, all context traffic is funneled through Playwright's local SOCKS interceptor (socksClientCertificatesInterceptor.ts), which then has to apply the user's proxy settings itself. It gets two cases wrong.

Case A: launch-level proxy is dropped

const browser = await chromium.launch({ proxy: { server: 'http://my-proxy:3128' } });
const context = await browser.newContext({
  clientCertificates: [{ origin: 'https://unrelated.example.com', certPath, keyPath }],
});
const page = await context.newPage();
await page.goto('http://localhost:PORT/empty.html');

Case B: proxy.bypass is ignored

const context = await browser.newContext({
  proxy: { server: 'http://my-proxy:3128', bypass: 'localhost' },
  clientCertificates: [{ origin: 'https://unrelated.example.com', certPath, keyPath }],
});
const page = await context.newPage();
await page.goto('http://localhost:PORT/empty.html');

Repro using the repo's proxyServer fixture (tests/library), with forwardTo(port, { allowConnectRequests: true }) so CONNECT tunnels are recorded:

Case Proxy received
launch proxy, no clientCertificates (control) requestUrls=["http://localhost:PORT/empty.html"]
launch proxy + clientCertificates connectHosts=[] requestUrls=[] (page loaded directly)
context proxy with bypass: 'localhost', no clientCertificates (control) nothing
same + clientCertificates connectHosts=["localhost:PORT"]

Expected behavior

Traffic with clientCertificates follows the same proxy rules as without: a launch-level proxy is used when the context has none, and hosts in proxy.bypass are connected to directly.

Actual behavior

  • With a launch-level proxy and no context-level proxy, every request goes direct and the proxy never sees it.
  • With a context-level proxy that has a bypass list, bypassed hosts are tunneled through the proxy anyway.

Both are silent: no error, just wrong routing.

Additional context

Root cause:

  • ClientCertificatesProxy only receives the context options (browser.ts newContext), so this._proxy = contextOptions.proxy never sees browser.options.proxy.
  • _getProxyAgent() calls createProxyAgent(this._proxy) without a forUrl, and createProxyAgent only evaluates proxy.bypass when a URL is supplied.

I intend to work on this and will send a PR.

Environment

- Operating System: macOS (Darwin 25.6.0)
- Node.js: 24.8.0
- Browser: Chromium (bundled r1246)
- Playwright: main @ 07f1a6154

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions