chore: remove glob from client-certificate matching (#31846)

Signed-off-by: Max Schmitt <max@schmitt.mx>
Co-authored-by: Dmitry Gozman <dgozman@gmail.com>
This commit is contained in:
Max Schmitt 2024-07-24 19:13:03 +02:00 committed by GitHub
parent ca149be154
commit 7570c25b3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 25 deletions

View File

@ -523,7 +523,7 @@ Does not enforce fixed viewport, allows resizing window in the headed mode.
## context-option-clientCertificates ## context-option-clientCertificates
- `clientCertificates` <[Array]<[Object]>> - `clientCertificates` <[Array]<[Object]>>
- `origin` <[string]> Glob pattern to match against the request origin that the certificate is valid for. - `origin` <[string]> Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
- `certPath` ?<[string]> Path to the file with the certificate in PEM format. - `certPath` ?<[string]> Path to the file with the certificate in PEM format.
- `keyPath` ?<[string]> Path to the file with the private key in PEM format. - `keyPath` ?<[string]> Path to the file with the private key in PEM format.
- `pfxPath` ?<[string]> Path to the PFX or PKCS12 encoded private key and certificate chain. - `pfxPath` ?<[string]> Path to the PFX or PKCS12 encoded private key and certificate chain.
@ -533,7 +533,7 @@ TLS Client Authentication allows the server to request a client certificate and
**Details** **Details**
An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be provided with a glob pattern to match the origins that the certificate is valid for. An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that the certificate is valid for.
:::note :::note
Using Client Certificates in combination with Proxy Servers is not supported. Using Client Certificates in combination with Proxy Servers is not supported.

View File

@ -21,7 +21,7 @@ import fs from 'fs';
import tls from 'tls'; import tls from 'tls';
import stream from 'stream'; import stream from 'stream';
import { createSocket } from '../utils/happy-eyeballs'; import { createSocket } from '../utils/happy-eyeballs';
import { globToRegex, isUnderTest, ManualPromise } from '../utils'; import { isUnderTest, ManualPromise } from '../utils';
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy'; import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../common/socksProxy';
import { SocksProxy } from '../common/socksProxy'; import { SocksProxy } from '../common/socksProxy';
import type * as channels from '@protocol/channels'; import type * as channels from '@protocol/channels';
@ -224,20 +224,16 @@ export class ClientCertificatesProxy {
} }
} }
const kClientCertificatesGlobRegex = Symbol('kClientCertificatesGlobRegex');
export function clientCertificatesToTLSOptions( export function clientCertificatesToTLSOptions(
clientCertificates: channels.BrowserNewContextOptions['clientCertificates'], clientCertificates: channels.BrowserNewContextOptions['clientCertificates'],
origin: string origin: string
): Pick<https.RequestOptions, 'pfx' | 'key' | 'cert'> | undefined { ): Pick<https.RequestOptions, 'pfx' | 'key' | 'cert'> | undefined {
const matchingCerts = clientCertificates?.filter(c => { const matchingCerts = clientCertificates?.filter(c => {
let regex: RegExp | undefined = (c as any)[kClientCertificatesGlobRegex]; try {
if (!regex) { return new URL(c.origin).origin === origin;
regex = globToRegex(c.origin); } catch (error) {
(c as any)[kClientCertificatesGlobRegex] = regex; return c.origin === origin;
} }
regex.lastIndex = 0;
return regex.test(origin);
}); });
if (!matchingCerts || !matchingCerts.length) if (!matchingCerts || !matchingCerts.length)
return; return;

View File

@ -13172,8 +13172,8 @@ export interface BrowserType<Unused = {}> {
* *
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a * An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the * single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be * certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
* provided with a glob pattern to match the origins that the certificate is valid for. * the certificate is valid for.
* *
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
* *
@ -13182,7 +13182,7 @@ export interface BrowserType<Unused = {}> {
*/ */
clientCertificates?: Array<{ clientCertificates?: Array<{
/** /**
* Glob pattern to match against the request origin that the certificate is valid for. * Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
*/ */
origin: string; origin: string;
@ -15583,8 +15583,8 @@ export interface APIRequest {
* *
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a * An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the * single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be * certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
* provided with a glob pattern to match the origins that the certificate is valid for. * the certificate is valid for.
* *
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
* *
@ -15593,7 +15593,7 @@ export interface APIRequest {
*/ */
clientCertificates?: Array<{ clientCertificates?: Array<{
/** /**
* Glob pattern to match against the request origin that the certificate is valid for. * Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
*/ */
origin: string; origin: string;
@ -16776,8 +16776,8 @@ export interface Browser extends EventEmitter {
* *
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a * An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the * single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be * certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
* provided with a glob pattern to match the origins that the certificate is valid for. * the certificate is valid for.
* *
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
* *
@ -16786,7 +16786,7 @@ export interface Browser extends EventEmitter {
*/ */
clientCertificates?: Array<{ clientCertificates?: Array<{
/** /**
* Glob pattern to match against the request origin that the certificate is valid for. * Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
*/ */
origin: string; origin: string;
@ -20226,8 +20226,8 @@ export interface BrowserContextOptions {
* *
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a * An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the * single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be * certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
* provided with a glob pattern to match the origins that the certificate is valid for. * the certificate is valid for.
* *
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
* *
@ -20236,7 +20236,7 @@ export interface BrowserContextOptions {
*/ */
clientCertificates?: Array<{ clientCertificates?: Array<{
/** /**
* Glob pattern to match against the request origin that the certificate is valid for. * Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
*/ */
origin: string; origin: string;

View File

@ -5208,8 +5208,8 @@ export interface PlaywrightTestOptions {
* *
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a * An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the * single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
* certficiate is encrypted. If the certificate is valid only for specific origins, the `origin` property should be * certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
* provided with a glob pattern to match the origins that the certificate is valid for. * the certificate is valid for.
* *
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
* *

View File

@ -248,6 +248,20 @@ test.describe('browser', () => {
await page.close(); await page.close();
}); });
test('should pass with matching certificates and trailing slash', async ({ browser, startCCServer, asset, browserName }) => {
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' });
const page = await browser.newPage({
clientCertificates: [{
origin: serverURL,
certPath: asset('client-certificates/client/trusted/cert.pem'),
keyPath: asset('client-certificates/client/trusted/key.pem'),
}],
});
await page.goto(serverURL);
await expect(page.getByText('Hello Alice, your certificate was issued by localhost!')).toBeVisible();
await page.close();
});
test('should have ignoreHTTPSErrors=false by default', async ({ browser, httpsServer, asset, browserName, platform }) => { test('should have ignoreHTTPSErrors=false by default', async ({ browser, httpsServer, asset, browserName, platform }) => {
const page = await browser.newPage({ const page = await browser.newPage({
clientCertificates: [{ clientCertificates: [{