icebear0828 Claude Opus 4.6 commited on
Commit
38895cf
·
1 Parent(s): 6b3630b

fix: use known-profile list instead of runtime detection for TLS impersonation

Browse files

The previous testProfile() approach using `curl -V` never validated
the --impersonate target. Worse, v1.5.x silently accepts unknown
profiles but applies NO impersonation (JA3 fingerprint = bare curl).

Replace runtime detection with a deterministic known-profile list.
Any configured chromeN is mapped to the nearest supported version
(e.g. chrome137 → chrome136). This works reliably across all
curl-impersonate versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. src/tls/curl-binary.ts +26 -34
src/tls/curl-binary.ts CHANGED
@@ -106,39 +106,34 @@ export function resolveCurlBinary(): string {
106
  return _resolved;
107
  }
108
 
109
- /** Test if a specific --impersonate profile is accepted by the binary. */
110
- function testProfile(binary: string, profile: string): boolean {
111
- try {
112
- execFileSync(binary, ["--impersonate", profile, "-V"], {
113
- encoding: "utf-8",
114
- timeout: 5000,
115
- stdio: ["ignore", "pipe", "pipe"],
116
- });
117
- return true;
118
- } catch {
119
- return false;
120
- }
121
- }
122
-
123
  /**
124
- * Find a working impersonate profile.
125
- * Tries the configured profile first, then descends Chrome versions.
 
126
  */
127
- function resolveProfile(binary: string, configured: string): string | null {
128
- if (testProfile(binary, configured)) return configured;
129
 
130
- const match = configured.match(/^chrome(\d+)/);
131
- if (!match) return null;
 
 
 
 
 
 
132
 
133
  const ver = parseInt(match[1], 10);
134
- for (let v = ver - 1; v >= ver - 10 && v > 0; v--) {
135
- const candidate = `chrome${v}`;
136
- if (testProfile(binary, candidate)) {
137
- console.warn(`[TLS] Profile "${configured}" not supported, using "${candidate}"`);
138
- return candidate;
139
- }
140
  }
141
- return null;
 
 
 
 
 
 
142
  }
143
 
144
  /**
@@ -154,13 +149,10 @@ function detectImpersonateSupport(binary: string): string[] {
154
  });
155
  if (helpOutput.includes("--impersonate")) {
156
  const configured = getConfig().tls.impersonate_profile ?? "chrome136";
157
- const profile = resolveProfile(binary, configured);
158
- if (profile) {
159
- _resolvedProfile = profile;
160
- console.log(`[TLS] Using --impersonate ${profile}`);
161
- return ["--impersonate", profile];
162
- }
163
- console.warn("[TLS] No supported impersonate profile found, using manual TLS args");
164
  }
165
  } catch {
166
  // --help failed, fall back to manual args
 
106
  return _resolved;
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  /**
110
+ * Chrome versions with distinct TLS fingerprints in curl-impersonate.
111
+ * Only these versions are valid --impersonate targets.
112
+ * Sorted ascending — update when curl-impersonate adds new profiles.
113
  */
114
+ const KNOWN_CHROME_PROFILES = [99, 100, 101, 104, 107, 110, 116, 119, 120, 123, 124, 131, 136];
 
115
 
116
+ /**
117
+ * Map a configured profile to the nearest known-supported version.
118
+ * e.g. "chrome137" → "chrome136", "chrome125" → "chrome124"
119
+ * Non-chrome profiles (e.g. "firefox") are passed through unchanged.
120
+ */
121
+ function resolveProfile(configured: string): string {
122
+ const match = configured.match(/^chrome(\d+)$/);
123
+ if (!match) return configured;
124
 
125
  const ver = parseInt(match[1], 10);
126
+ let best: number | undefined;
127
+ for (const known of KNOWN_CHROME_PROFILES) {
128
+ if (known <= ver) best = known;
 
 
 
129
  }
130
+ if (!best) return configured;
131
+
132
+ const resolved = `chrome${best}`;
133
+ if (resolved !== configured) {
134
+ console.warn(`[TLS] Profile "${configured}" not in known targets, using "${resolved}"`);
135
+ }
136
+ return resolved;
137
  }
138
 
139
  /**
 
149
  });
150
  if (helpOutput.includes("--impersonate")) {
151
  const configured = getConfig().tls.impersonate_profile ?? "chrome136";
152
+ const profile = resolveProfile(configured);
153
+ _resolvedProfile = profile;
154
+ console.log(`[TLS] Using --impersonate ${profile}`);
155
+ return ["--impersonate", profile];
 
 
 
156
  }
157
  } catch {
158
  // --help failed, fall back to manual args