@browsercore/profiles 0.1.4 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  # @browsercore/profiles
2
2
 
3
-
4
3
  [![npm version](https://img.shields.io/npm/v/@browsercore/profiles)](https://www.npmjs.com/package/@browsercore/profiles)
5
- [![coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jverneuer/browsercore-profiles/main/coverage/badge.json)](https://github.com/jverneuer/browsercore-profiles/blob/main/COVERAGE.md)
4
+ [![coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jverneuer/browsercore-profiles/coverage/coverage/badge.json)](https://github.com/jverneuer/browsercore-profiles/blob/main/COVERAGE.md)
6
5
  [![lint](https://img.shields.io/github/actions/workflow/status/jverneuer/browsercore-profiles/ci.yml?label=lint)](https://github.com/jverneuer/browsercore-profiles/actions/workflows/ci.yml)
7
6
 
8
- Browser fingerprint definitions (TLS / HTTP/2 / HTTP/1.1). Pure data — no protocol implementation.
7
+ Browser fingerprint definitions (TLS / HTTP/2 / HTTP/1.1). Pure data — no protocol implementation lives here. Higher layers read these definitions and translate them into bytes, header order, and SETTINGS frames.
9
8
 
10
9
  ## Responsibility
11
10
 
12
- Define WHAT a browser fingerprint looks like so that higher layers (tls, http1, http2) can translate it into bytes, header order, and SETTINGS frames. Adding a new Chrome version means adding a new entry here — protocol implementations never change.
11
+ Define WHAT a browser fingerprint looks like: ordered cipher suites, TLS extension order, GREASE behavior, HTTP/2 SETTINGS, and HTTP/1.1 header order. Adding a new Chrome version means adding a new entry here — protocol implementations never change.
13
12
 
14
13
  ## What it does NOT know about
15
14
 
@@ -18,34 +17,64 @@ Define WHAT a browser fingerprint looks like so that higher layers (tls, http1,
18
17
  - Sockets or I/O
19
18
  - Cookies
20
19
 
21
- ## Public API
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install @browsercore/profiles
24
+ ```
25
+
26
+ ## Quick usage
22
27
 
23
28
  ```ts
24
29
  import { getProfile, listProfiles, registerProfile } from "@browsercore/profiles";
30
+ import type { ProfileId } from "@browsercore/profiles";
25
31
 
26
32
  const chrome = getProfile("chrome-140" as ProfileId);
27
33
  console.log(chrome.tls.cipherSuites); // ordered cipher list
28
- console.log(chrome.http2.settings); // HTTP/2 SETTINGS frame values
34
+ console.log(chrome.http2.settings); // HTTP/2 SETTINGS frame values
29
35
 
30
- const all = listProfiles(); // ["chrome-120", "chrome-128", ...]
36
+ const all = listProfiles(); // ["chrome-120", "chrome-128", ...] — insertion order
31
37
 
32
38
  registerProfile(myCustomProfile); // extensibility hook
33
39
  ```
34
40
 
35
- ## Types
41
+ ## Public API
36
42
 
37
43
  | Export | Kind | Purpose |
38
44
  | --- | --- | --- |
45
+ | `getProfile()` | function | Look up a profile by id (throws `UnknownProfileError` if absent) |
46
+ | `listProfiles()` | function | List every registered id, in insertion order |
47
+ | `registerProfile()` | function | Register or overwrite a custom profile at runtime |
48
+ | `diffProfiles()` | function | Field-by-field diff of two profiles, reporting each differing path |
49
+ | `DiffOptions` | interface | Diff tuning (e.g. order-sensitive vs. multiset array comparison) |
50
+ | `ProfileDiff` | interface | A single difference located by its dotted path |
51
+ | `buildExpectedClientHello()` | function | Project a profile's TLS fields onto expected wire codes |
52
+ | `validateProfileAgainstCapture()` | function | Validate a profile against a captured ClientHello |
53
+ | `ValidationResult` | interface | `{ ok, diffs }` outcome of validation |
54
+ | `TlsCapture` | interface | A captured ClientHello parsed out of a packet capture |
55
+ | `ClientHelloExpected` | interface | The wire values a profile's ClientHello should carry |
39
56
  | `BrowserProfile` | interface | Complete fingerprint across TLS + HTTP/2 + HTTP/1.1 |
40
57
  | `TlsProfile` | interface | Cipher order, extensions, GREASE, signature algorithms |
41
58
  | `Http2Profile` | interface | SETTINGS, window sizes, priority |
59
+ | `Http2Settings` | interface | HTTP/2 numeric settings (RFC 9113 §6.5.1) |
60
+ | `Http2Priority` | interface | Stream priority descriptor |
42
61
  | `Http1Profile` | interface | Default headers, header order, accept-encoding |
43
- | `ProfileId` | branded string | Opaque profile identifier |
62
+ | `ProfileId` | branded type | Opaque profile identifier (`"chrome-140"`) |
44
63
  | `ProfileName` | literal union | `"chrome" \| "firefox" \| "safari" \| "edge"` |
45
- | `getProfile()` | function | Look up a profile by id |
46
- | `listProfiles()` | function | List all registered ids |
47
- | `registerProfile()` | function | Add a custom profile at runtime |
64
+ | `ChromeProfiles` / `FirefoxProfiles` / `SafariProfiles` / `EdgeProfiles` | const maps | Per-browser profile definitions |
65
+ | `assertNever()` | function | Exhaustiveness check for switches over unions |
66
+ | `ProfileError` | class | Base typed error (matched on `kind`) |
48
67
  | `UnknownProfileError` | class | Thrown when a profile id is not found |
68
+ | `ValidationError` | class | Thrown on an unknown profile value or bad capture |
69
+
70
+ ## Shipped profiles
71
+
72
+ | Browser | Profiles |
73
+ | --- | --- |
74
+ | Chrome | `chrome-120`, `chrome-128`, `chrome-140` |
75
+ | Firefox | `firefox-120`, `firefox-128`, `firefox-135` |
76
+ | Safari | `safari-17`, `safari-18` |
77
+ | Edge | `edge-120`, `edge-128` |
49
78
 
50
79
  ## Dependency graph
51
80
 
@@ -53,4 +82,73 @@ registerProfile(myCustomProfile); // extensibility hook
53
82
  @browsercore/profiles
54
83
  ```
55
84
 
56
- No other `@browsercore/*` packages and no Node built-ins are imported. This is a pure data package.
85
+ No other `@browsercore/*` runtime packages and no Node built-ins are imported. This is a pure data package. `@browsercore/dev` is a dev-only dependency that supplies shared build / lint / test configuration (see [Shared config](#shared-config)).
86
+
87
+ ## Source layout
88
+
89
+ ```
90
+ src/
91
+ ├─ index.ts Public API surface — re-exports from the rest of the package
92
+ ├─ index.internal.ts Barrel re-exporting the per-browser profile maps
93
+ ├─ registry.ts getProfile / listProfiles / registerProfile (Map-backed)
94
+ ├─ diff.ts diffProfiles — field-by-field diff of two profiles
95
+ ├─ validate.ts buildExpectedClientHello / validateProfileAgainstCapture
96
+ ├─ codes.ts IANA TLS registry codes (cipher suites, groups, versions, sig schemes)
97
+ ├─ errors.ts ProfileError / UnknownProfileError / ValidationError
98
+ ├─ types.ts BrowserProfile + per-layer profile interfaces
99
+ ├─ utils.ts assertNever / createId
100
+ └─ profiles/ Per-browser profile definitions
101
+ ├─ chrome.ts chrome-120, chrome-128, chrome-140
102
+ ├─ firefox.ts firefox-120, firefox-128, firefox-135
103
+ ├─ safari.ts safari-17, safari-18
104
+ └─ edge.ts edge-120, edge-128
105
+ ```
106
+
107
+ ## Development
108
+
109
+ Requires **Node >= 26**. ESM only (`"type": "module"`).
110
+
111
+ ```sh
112
+ npm install # installs @browsercore/dev (file:../dev) + siblings
113
+ npm run build # tsc -p tsconfig.build.json (emit to dist/)
114
+ npm run typecheck
115
+ npm run lint # oxlint --type-aware src/
116
+ npm test # vitest run
117
+ ```
118
+
119
+ Run a single test file:
120
+
121
+ ```sh
122
+ npx vitest run tests/profiles.test.ts
123
+ ```
124
+
125
+ Run tests by name pattern:
126
+
127
+ ```sh
128
+ npx vitest run -t "returns a known Chrome profile by id"
129
+ ```
130
+
131
+ Generate a coverage report:
132
+
133
+ ```sh
134
+ npm test -- --coverage
135
+ node ../dev/bin/coverage-md.mjs # writes COVERAGE.md + coverage/badge.json
136
+ ```
137
+
138
+ ### Shared config
139
+
140
+ This package adopts `@browsercore/dev`, the shared config package for the
141
+ `@browsercore/*` family. Configuration is centralized — this repo only wires it in:
142
+
143
+ | Concern | Mechanism |
144
+ | --- | --- |
145
+ | TypeScript strict flags | `tsconfig.json` extends `@browsercore/dev/tsconfig.base.json` |
146
+ | Vitest config | `vitest.config.ts` calls `definePackageConfig({ name: "profiles" })` |
147
+ | Oxlint config | `oxlint.config.ts` extends `@browsercore/dev/oxlint` |
148
+ | Coverage report | `coverage-md` bin from `@browsercore/dev` |
149
+
150
+ `@browsercore/dev` is declared as a devDependency via `"@browsercore/dev": "file:../dev"`.
151
+
152
+ ## License
153
+
154
+ MIT
@@ -0,0 +1,40 @@
1
+ /**
2
+ * IANA TLS registry codes used to project profile names onto wire values.
3
+ *
4
+ * These are the canonical 2-byte codes from the IANA TLS parameter registries.
5
+ * Only the codes referenced by the shipped profiles are mapped here — an
6
+ * unknown name is a bug in a profile definition and surfaces as a
7
+ * {@link ValidationError} at projection time, so the tables double as an
8
+ * allow-list that keeps profile data honest.
9
+ *
10
+ * Registries:
11
+ * - Cipher suites: tls-parameters.xhtml#tls-parameters-4
12
+ * - Named groups: tls-parameters.xhtml#tls-parameters-8
13
+ * - Signature schemes: tls-parameters.xhtml#tls-parameters-16
14
+ */
15
+ /**
16
+ * The name Chrome/Edge use in their cipher list to mark a GREASE slot (RFC 8701).
17
+ * The real value is randomized per-connection (0x0a0a..0xfafa); validation accepts
18
+ * any GREASE-pattern byte pair at a slot marked with this placeholder.
19
+ */
20
+ export declare const CIPHER_GREASE_PLACEHOLDER = "TLS_GREASE_RESERVED_0";
21
+ /** Selected IANA TLS Cipher Suite codes, keyed by the canonical suite name used in profiles. */
22
+ export declare const CIPHER_SUITE_CODES: Readonly<Record<string, number>>;
23
+ /** Selected IANA TLS Supported Groups (named groups) codes. */
24
+ export declare const NAMED_GROUP_CODES: Readonly<Record<string, number>>;
25
+ /** Selected IANA TLS SignatureScheme codes. */
26
+ export declare const SIGNATURE_SCHEME_CODES: Readonly<Record<string, number>>;
27
+ /** IANA TLS ProtocolVersion codes for the supported_versions extension. */
28
+ export declare const VERSION_CODES: Readonly<Record<string, number>>;
29
+ /**
30
+ * Map a cipher-suite name to its 2-byte IANA wire code.
31
+ *
32
+ * This is the single projection seam from a profile's cipher name to the bytes
33
+ * a ClientHello carries. It throws on an unknown name rather than returning a
34
+ * sentinel: 0x0000 would be ambiguous (it collides with
35
+ * TLS_EMPTY_RENEGOTIATION_INFO_SCSV), and a silent default would hide a bug in
36
+ * a profile definition. An unknown name is therefore always an error here,
37
+ * never a 0x0000 fallback.
38
+ */
39
+ export declare function cipherSuiteToWire(name: string): number;
40
+ //# sourceMappingURL=codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,gGAAgG;AAChG,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkC/D,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY9D,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAanE,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK1D,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD"}
package/dist/codes.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * IANA TLS registry codes used to project profile names onto wire values.
3
+ *
4
+ * These are the canonical 2-byte codes from the IANA TLS parameter registries.
5
+ * Only the codes referenced by the shipped profiles are mapped here — an
6
+ * unknown name is a bug in a profile definition and surfaces as a
7
+ * {@link ValidationError} at projection time, so the tables double as an
8
+ * allow-list that keeps profile data honest.
9
+ *
10
+ * Registries:
11
+ * - Cipher suites: tls-parameters.xhtml#tls-parameters-4
12
+ * - Named groups: tls-parameters.xhtml#tls-parameters-8
13
+ * - Signature schemes: tls-parameters.xhtml#tls-parameters-16
14
+ */
15
+ import { ProfileError } from "./errors.js";
16
+ /**
17
+ * The name Chrome/Edge use in their cipher list to mark a GREASE slot (RFC 8701).
18
+ * The real value is randomized per-connection (0x0a0a..0xfafa); validation accepts
19
+ * any GREASE-pattern byte pair at a slot marked with this placeholder.
20
+ */
21
+ export const CIPHER_GREASE_PLACEHOLDER = "TLS_GREASE_RESERVED_0";
22
+ /** Selected IANA TLS Cipher Suite codes, keyed by the canonical suite name used in profiles. */
23
+ export const CIPHER_SUITE_CODES = {
24
+ // GREASE: real value is randomized per-connection (0x0a0a..0xfafa). We use the
25
+ // first canonical GREASE code for the expected representation; validation
26
+ // accepts any GREASE-pattern value at a GREASE slot.
27
+ [CIPHER_GREASE_PLACEHOLDER]: 0x0a0a,
28
+ TLS_AES_128_GCM_SHA256: 0x1301,
29
+ TLS_AES_256_GCM_SHA384: 0x1302,
30
+ TLS_CHACHA20_POLY1305_SHA256: 0x1303,
31
+ TLS_AES_128_CCM_SHA256: 0x1304,
32
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 0xc02b,
33
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: 0xc02f,
34
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 0xc02c,
35
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: 0xc030,
36
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: 0xcca9,
37
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: 0xcca8,
38
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 0xc013,
39
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: 0xc014,
40
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: 0xc009,
41
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: 0xc00a,
42
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: 0xc023,
43
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: 0xc024,
44
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: 0xc027,
45
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: 0xc028,
46
+ TLS_RSA_WITH_AES_128_GCM_SHA256: 0x009c,
47
+ TLS_RSA_WITH_AES_256_GCM_SHA384: 0x009d,
48
+ TLS_RSA_WITH_AES_128_CBC_SHA: 0x002f,
49
+ TLS_RSA_WITH_AES_256_CBC_SHA: 0x0035,
50
+ TLS_RSA_WITH_AES_128_CBC_SHA256: 0x003c,
51
+ TLS_RSA_WITH_AES_256_CBC_SHA256: 0x003d,
52
+ // Safari legacy tail: 3DES ciphers (RFC 3268). BoringSSL dropped these, but
53
+ // curl-impersonate restores them so Safari's ClientHello matches byte-for-byte.
54
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: 0xc008,
55
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: 0xc012,
56
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA: 0x000a,
57
+ };
58
+ /** Selected IANA TLS Supported Groups (named groups) codes. */
59
+ export const NAMED_GROUP_CODES = {
60
+ x25519: 0x001d,
61
+ secp256r1: 0x0017,
62
+ secp384r1: 0x0018,
63
+ secp521r1: 0x0019,
64
+ ffdhe2048: 0x0100,
65
+ ffdhe3072: 0x0101,
66
+ // Chrome 124+ adds the hybrid post-quantum group. The draft Kyber768 code
67
+ // (0x6399) shipped in Chrome 124–130; the final MLKEM768 code (0x11ec) has
68
+ // been used since Chrome 131. Both appear at the front of the group list.
69
+ X25519Kyber768: 0x6399,
70
+ X25519MLKEM768: 0x11ec,
71
+ };
72
+ /** Selected IANA TLS SignatureScheme codes. */
73
+ export const SIGNATURE_SCHEME_CODES = {
74
+ ecdsa_secp256r1_sha256: 0x0403,
75
+ ecdsa_secp384r1_sha384: 0x0503,
76
+ ecdsa_secp521r1_sha512: 0x0603,
77
+ ecdsa_sha1: 0x0203,
78
+ rsa_pss_rsae_sha256: 0x0804,
79
+ rsa_pss_rsae_sha384: 0x0805,
80
+ rsa_pss_rsae_sha512: 0x0806,
81
+ rsa_pkcs1_sha256: 0x0401,
82
+ rsa_pkcs1_sha384: 0x0501,
83
+ rsa_pkcs1_sha512: 0x0601,
84
+ rsa_pkcs1_sha1: 0x0201,
85
+ ed25519: 0x0807,
86
+ };
87
+ /** IANA TLS ProtocolVersion codes for the supported_versions extension. */
88
+ export const VERSION_CODES = {
89
+ "TLS 1.3": 0x0304,
90
+ "TLS 1.2": 0x0303,
91
+ "TLS 1.1": 0x0302,
92
+ "TLS 1.0": 0x0301,
93
+ };
94
+ /**
95
+ * Map a cipher-suite name to its 2-byte IANA wire code.
96
+ *
97
+ * This is the single projection seam from a profile's cipher name to the bytes
98
+ * a ClientHello carries. It throws on an unknown name rather than returning a
99
+ * sentinel: 0x0000 would be ambiguous (it collides with
100
+ * TLS_EMPTY_RENEGOTIATION_INFO_SCSV), and a silent default would hide a bug in
101
+ * a profile definition. An unknown name is therefore always an error here,
102
+ * never a 0x0000 fallback.
103
+ */
104
+ export function cipherSuiteToWire(name) {
105
+ const code = CIPHER_SUITE_CODES[name];
106
+ if (code === undefined) {
107
+ throw new ProfileError("UnknownCipherSuite", `Unknown cipher suite: ${name}`);
108
+ }
109
+ return code;
110
+ }
111
+ //# sourceMappingURL=codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codes.js","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEjE,gGAAgG;AAChG,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAChE,+EAA+E;IAC/E,0EAA0E;IAC1E,qDAAqD;IACrD,CAAC,yBAAyB,CAAC,EAAE,MAAM;IACnC,sBAAsB,EAAE,MAAM;IAC9B,sBAAsB,EAAE,MAAM;IAC9B,4BAA4B,EAAE,MAAM;IACpC,sBAAsB,EAAE,MAAM;IAC9B,uCAAuC,EAAE,MAAM;IAC/C,qCAAqC,EAAE,MAAM;IAC7C,uCAAuC,EAAE,MAAM;IAC/C,qCAAqC,EAAE,MAAM;IAC7C,6CAA6C,EAAE,MAAM;IACrD,2CAA2C,EAAE,MAAM;IACnD,kCAAkC,EAAE,MAAM;IAC1C,kCAAkC,EAAE,MAAM;IAC1C,oCAAoC,EAAE,MAAM;IAC5C,oCAAoC,EAAE,MAAM;IAC5C,uCAAuC,EAAE,MAAM;IAC/C,uCAAuC,EAAE,MAAM;IAC/C,qCAAqC,EAAE,MAAM;IAC7C,qCAAqC,EAAE,MAAM;IAC7C,+BAA+B,EAAE,MAAM;IACvC,+BAA+B,EAAE,MAAM;IACvC,4BAA4B,EAAE,MAAM;IACpC,4BAA4B,EAAE,MAAM;IACpC,+BAA+B,EAAE,MAAM;IACvC,+BAA+B,EAAE,MAAM;IACvC,4EAA4E;IAC5E,gFAAgF;IAChF,qCAAqC,EAAE,MAAM;IAC7C,mCAAmC,EAAE,MAAM;IAC3C,6BAA6B,EAAE,MAAM;CACxC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAqC;IAC/D,MAAM,EAAE,MAAM;IACd,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;CACzB,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACpE,sBAAsB,EAAE,MAAM;IAC9B,sBAAsB,EAAE,MAAM;IAC9B,sBAAsB,EAAE,MAAM;IAC9B,UAAU,EAAE,MAAM;IAClB,mBAAmB,EAAE,MAAM;IAC3B,mBAAmB,EAAE,MAAM;IAC3B,mBAAmB,EAAE,MAAM;IAC3B,gBAAgB,EAAE,MAAM;IACxB,gBAAgB,EAAE,MAAM;IACxB,gBAAgB,EAAE,MAAM;IACxB,cAAc,EAAE,MAAM;IACtB,OAAO,EAAE,MAAM;CAClB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAqC;IAC3D,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;CACpB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,YAAY,CAAC,oBAAoB,EAAE,yBAAyB,IAAI,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
package/dist/diff.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,8 @@ export { getProfile, listProfiles, registerProfile, } from "./registry.js";
9
9
  export { diffProfiles, } from "./diff.js";
10
10
  export type { DiffOptions, ProfileDiff, } from "./diff.js";
11
11
  export { buildExpectedClientHello, validateProfileAgainstCapture, ValidationError, } from "./validate.js";
12
- export type { TlsCapture, ClientHelloExpected, } from "./validate.js";
12
+ export type { TlsCapture, ClientHelloExpected, ValidationResult, } from "./validate.js";
13
+ export { cipherSuiteToWire, CIPHER_GREASE_PLACEHOLDER, CIPHER_SUITE_CODES, NAMED_GROUP_CODES, SIGNATURE_SCHEME_CODES, VERSION_CODES, } from "./codes.js";
13
14
  export { ChromeProfiles, FirefoxProfiles, SafariProfiles, EdgeProfiles, } from "./index.internal.js";
14
15
  export { ProfileError, UnknownProfileError, } from "./errors.js";
15
16
  export type { BrowserProfile, Http1Profile, Http2Profile, Http2Settings, Http2Priority, ProfileId, ProfileName, TlsProfile, } from "./types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,UAAU,EACV,YAAY,EACZ,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,YAAY,GACf,MAAM,WAAW,CAAC;AAEnB,YAAY,EACR,WAAW,EACX,WAAW,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EACH,wBAAwB,EACxB,6BAA6B,EAC7B,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACR,UAAU,EACV,mBAAmB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,YAAY,EACZ,mBAAmB,GACtB,MAAM,aAAa,CAAC;AAErB,YAAY,EACR,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,SAAS,EACT,WAAW,EACX,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,UAAU,EACV,YAAY,EACZ,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,YAAY,GACf,MAAM,WAAW,CAAC;AAEnB,YAAY,EACR,WAAW,EACX,WAAW,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EACH,wBAAwB,EACxB,6BAA6B,EAC7B,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACR,UAAU,EACV,mBAAmB,EACnB,gBAAgB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,YAAY,EACZ,mBAAmB,GACtB,MAAM,aAAa,CAAC;AAErB,YAAY,EACR,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,SAAS,EACT,WAAW,EACX,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@
8
8
  export { getProfile, listProfiles, registerProfile, } from "./registry.js";
9
9
  export { diffProfiles, } from "./diff.js";
10
10
  export { buildExpectedClientHello, validateProfileAgainstCapture, ValidationError, } from "./validate.js";
11
+ export { cipherSuiteToWire, CIPHER_GREASE_PLACEHOLDER, CIPHER_SUITE_CODES, NAMED_GROUP_CODES, SIGNATURE_SCHEME_CODES, VERSION_CODES, } from "./codes.js";
11
12
  export { ChromeProfiles, FirefoxProfiles, SafariProfiles, EdgeProfiles, } from "./index.internal.js";
12
13
  export { ProfileError, UnknownProfileError, } from "./errors.js";
13
14
  export { assertNever } from "./utils.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,UAAU,EACV,YAAY,EACZ,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,YAAY,GACf,MAAM,WAAW,CAAC;AAOnB,OAAO,EACH,wBAAwB,EACxB,6BAA6B,EAC7B,eAAe,GAClB,MAAM,eAAe,CAAC;AAOvB,OAAO,EACH,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,YAAY,EACZ,mBAAmB,GACtB,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,UAAU,EACV,YAAY,EACZ,eAAe,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACH,YAAY,GACf,MAAM,WAAW,CAAC;AAOnB,OAAO,EACH,wBAAwB,EACxB,6BAA6B,EAC7B,eAAe,GAClB,MAAM,eAAe,CAAC;AAQvB,OAAO,EACH,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,YAAY,EACZ,mBAAmB,GACtB,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -1,10 +1,23 @@
1
1
  /**
2
2
  * Chrome fingerprint definitions.
3
3
  *
4
- * TLS values mirror real Chrome ClientHello captures (JA3 / JA4 style). Chrome
5
- * enables GREASE (RFC 8701), advertises TLS 1.3, and sends a stable cipher order
6
- * per release. HTTP/2 settings track Chrome's real SETTINGS frame. Values are
7
- * accurate for the listed versions unless noted otherwise.
4
+ * TLS values are byte-accurate against real curl-impersonate ClientHello
5
+ * captures. The authoritative ground truth is the lwthiker/curl-impersonate
6
+ * wire captures (testing-worktree/captures/_probe/output/chrome*.json) together
7
+ * with their reported ja3 / ja4 / peetprint fingerprints. Every value here is
8
+ * verified against those captures:
9
+ *
10
+ * - chrome-120: ja3 698f6d684588ddc1217dfb4454916129, peetprint
11
+ * 8ad9325e12f531d2983b78860de7b0ec (no post-quantum group).
12
+ * - chrome-124..130: X25519Kyber768 (0x6399) added to supported_groups.
13
+ * - chrome-131+: X25519MLKEM768 (0x11ec) replaces Kyber768; the
14
+ * application_settings extension moves from 17513 to 17613.
15
+ *
16
+ * Chrome permutes its extension order at runtime (tls_permute_extensions), so
17
+ * `extensionOrder` stores the canonical pre-permutation seed that
18
+ * curl-impersonate configures — matching the peetprint's normalized order.
19
+ * GREASE slots are tracked separately via the `grease` flag; the runtime
20
+ * randomizes the actual 0x?a?a values per RFC 8701.
8
21
  */
9
22
  import type { BrowserProfile } from "../types.js";
10
23
  export declare const chrome120: BrowserProfile;
@@ -1 +1 @@
1
- {"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../src/profiles/chrome.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAkD7D,eAAO,MAAM,SAAS,EAAE,cAoDvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cAoDvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cAoDvB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;CAIjB,CAAC"}
1
+ {"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../src/profiles/chrome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAwF7D,eAAO,MAAM,SAAS,EAAE,cA+BvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cA+BvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cA+BvB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;CAIjB,CAAC"}
@@ -1,19 +1,39 @@
1
1
  /**
2
2
  * Chrome fingerprint definitions.
3
3
  *
4
- * TLS values mirror real Chrome ClientHello captures (JA3 / JA4 style). Chrome
5
- * enables GREASE (RFC 8701), advertises TLS 1.3, and sends a stable cipher order
6
- * per release. HTTP/2 settings track Chrome's real SETTINGS frame. Values are
7
- * accurate for the listed versions unless noted otherwise.
4
+ * TLS values are byte-accurate against real curl-impersonate ClientHello
5
+ * captures. The authoritative ground truth is the lwthiker/curl-impersonate
6
+ * wire captures (testing-worktree/captures/_probe/output/chrome*.json) together
7
+ * with their reported ja3 / ja4 / peetprint fingerprints. Every value here is
8
+ * verified against those captures:
9
+ *
10
+ * - chrome-120: ja3 698f6d684588ddc1217dfb4454916129, peetprint
11
+ * 8ad9325e12f531d2983b78860de7b0ec (no post-quantum group).
12
+ * - chrome-124..130: X25519Kyber768 (0x6399) added to supported_groups.
13
+ * - chrome-131+: X25519MLKEM768 (0x11ec) replaces Kyber768; the
14
+ * application_settings extension moves from 17513 to 17613.
15
+ *
16
+ * Chrome permutes its extension order at runtime (tls_permute_extensions), so
17
+ * `extensionOrder` stores the canonical pre-permutation seed that
18
+ * curl-impersonate configures — matching the peetprint's normalized order.
19
+ * GREASE slots are tracked separately via the `grease` flag; the runtime
20
+ * randomizes the actual 0x?a?a values per RFC 8701.
8
21
  */
9
22
  /** TLS 1.3 GREASE placeholder cipher (0x?a?a) Chrome inserts at the top of the list. */
10
23
  const GREASE = "TLS_GREASE_RESERVED_0";
24
+ /**
25
+ * Canonical (pre-permutation) Chrome extension order.
26
+ *
27
+ * Mirrors the peetprint-normalized order `0-10-11-13-16-APP_SETTINGS-18-23-27-
28
+ * 35-43-45-5-51-65037-65281`. The only version-dependent slot is the
29
+ * application_settings extension: 17513 (application_settings_old) through
30
+ * chrome ~131, then 17613 (application_settings) from chrome ~132 onward.
31
+ */
32
+ const chromeExtensionOrder = (appSettings) => [
33
+ 0, 10, 11, 13, 16, appSettings, 18, 23, 27, 35, 43, 45, 5, 51, 65037, 65281,
34
+ ];
11
35
  const chromeTlsBase = {
12
- extensionOrder: [
13
- 0, 10, 11, 13, 16, 17513, 18, 23, 27, 35, 41, 43, 45, 5, 51, 65281,
14
- ],
15
36
  supportedVersions: ["TLS 1.3", "TLS 1.2"],
16
- keyShareGroups: ["x25519", "secp256r1"],
17
37
  signatureAlgorithms: [
18
38
  "ecdsa_secp256r1_sha256",
19
39
  "rsa_pss_rsae_sha256",
@@ -21,6 +41,8 @@ const chromeTlsBase = {
21
41
  "ecdsa_secp384r1_sha384",
22
42
  "rsa_pss_rsae_sha384",
23
43
  "rsa_pkcs1_sha384",
44
+ "rsa_pss_rsae_sha512",
45
+ "rsa_pkcs1_sha512",
24
46
  ],
25
47
  grease: true,
26
48
  };
@@ -30,6 +52,14 @@ const chromeHttp2Base = {
30
52
  headerTableSize: 65536,
31
53
  weight: 256,
32
54
  };
55
+ const chromeHttp2Settings = {
56
+ headerTableSize: 65536,
57
+ enablePush: false,
58
+ maxConcurrentStreams: 100,
59
+ initialWindowSize: 6291456,
60
+ maxFrameSize: 16384,
61
+ maxHeaderListSize: 262144,
62
+ };
33
63
  const chromeHttp1Base = {
34
64
  connection: "keep-alive",
35
65
  acceptEncoding: "gzip, deflate, br",
@@ -50,40 +80,37 @@ const chromeHttp1Base = {
50
80
  "accept-language",
51
81
  ],
52
82
  };
83
+ const chromeCipherSuites = [
84
+ GREASE,
85
+ "TLS_AES_128_GCM_SHA256",
86
+ "TLS_AES_256_GCM_SHA384",
87
+ "TLS_CHACHA20_POLY1305_SHA256",
88
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
89
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
90
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
91
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
92
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
93
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
94
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
95
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
96
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
97
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
98
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
99
+ "TLS_RSA_WITH_AES_256_CBC_SHA",
100
+ ];
53
101
  export const chrome120 = {
54
102
  id: "chrome-120",
55
103
  name: "chrome",
56
104
  version: "120.0.6099.71",
57
105
  tls: {
58
106
  ...chromeTlsBase,
59
- cipherSuites: [
60
- GREASE,
61
- "TLS_AES_128_GCM_SHA256",
62
- "TLS_AES_256_GCM_SHA384",
63
- "TLS_CHACHA20_POLY1305_SHA256",
64
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
65
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
66
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
67
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
68
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
69
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
70
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
71
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
72
- "TLS_RSA_WITH_AES_128_GCM_SHA256",
73
- "TLS_RSA_WITH_AES_256_GCM_SHA384",
74
- "TLS_RSA_WITH_AES_128_CBC_SHA",
75
- "TLS_RSA_WITH_AES_256_CBC_SHA",
76
- ],
107
+ extensionOrder: chromeExtensionOrder(17513),
108
+ keyShareGroups: ["x25519", "secp256r1", "secp384r1"],
109
+ cipherSuites: chromeCipherSuites,
77
110
  },
78
111
  http2: {
79
112
  ...chromeHttp2Base,
80
- settings: {
81
- headerTableSize: 65536,
82
- enablePush: false,
83
- maxConcurrentStreams: 100,
84
- initialWindowSize: 6291456,
85
- maxFrameSize: 16384,
86
- },
113
+ settings: chromeHttp2Settings,
87
114
  },
88
115
  http1: {
89
116
  ...chromeHttp1Base,
@@ -108,34 +135,13 @@ export const chrome128 = {
108
135
  version: "128.0.6613.137",
109
136
  tls: {
110
137
  ...chromeTlsBase,
111
- cipherSuites: [
112
- GREASE,
113
- "TLS_AES_128_GCM_SHA256",
114
- "TLS_AES_256_GCM_SHA384",
115
- "TLS_CHACHA20_POLY1305_SHA256",
116
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
117
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
118
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
119
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
120
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
121
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
122
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
123
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
124
- "TLS_RSA_WITH_AES_128_GCM_SHA256",
125
- "TLS_RSA_WITH_AES_256_GCM_SHA384",
126
- "TLS_RSA_WITH_AES_128_CBC_SHA",
127
- "TLS_RSA_WITH_AES_256_CBC_SHA",
128
- ],
138
+ extensionOrder: chromeExtensionOrder(17513),
139
+ keyShareGroups: ["X25519Kyber768", "x25519", "secp256r1", "secp384r1"],
140
+ cipherSuites: chromeCipherSuites,
129
141
  },
130
142
  http2: {
131
143
  ...chromeHttp2Base,
132
- settings: {
133
- headerTableSize: 65536,
134
- enablePush: false,
135
- maxConcurrentStreams: 100,
136
- initialWindowSize: 6291456,
137
- maxFrameSize: 16384,
138
- },
144
+ settings: chromeHttp2Settings,
139
145
  },
140
146
  http1: {
141
147
  ...chromeHttp1Base,
@@ -160,34 +166,13 @@ export const chrome140 = {
160
166
  version: "140.0.7339.18",
161
167
  tls: {
162
168
  ...chromeTlsBase,
163
- cipherSuites: [
164
- GREASE,
165
- "TLS_AES_128_GCM_SHA256",
166
- "TLS_AES_256_GCM_SHA384",
167
- "TLS_CHACHA20_POLY1305_SHA256",
168
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
169
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
170
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
171
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
172
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
173
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
174
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
175
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
176
- "TLS_RSA_WITH_AES_128_GCM_SHA256",
177
- "TLS_RSA_WITH_AES_256_GCM_SHA384",
178
- "TLS_RSA_WITH_AES_128_CBC_SHA",
179
- "TLS_RSA_WITH_AES_256_CBC_SHA",
180
- ],
169
+ extensionOrder: chromeExtensionOrder(17613),
170
+ keyShareGroups: ["X25519MLKEM768", "x25519", "secp256r1", "secp384r1"],
171
+ cipherSuites: chromeCipherSuites,
181
172
  },
182
173
  http2: {
183
174
  ...chromeHttp2Base,
184
- settings: {
185
- headerTableSize: 65536,
186
- enablePush: false,
187
- maxConcurrentStreams: 100,
188
- initialWindowSize: 6291456,
189
- maxFrameSize: 16384,
190
- },
175
+ settings: chromeHttp2Settings,
191
176
  },
192
177
  http1: {
193
178
  ...chromeHttp1Base,