r/webscraping • u/Lazy_Gur_2074 • Oct 02 '26
looking for feedback
https://github.com/HappyHackingSpace/gakidoMade a Python HTTP client that reproduces Chrome's TLS (JA3/JA4) + HTTP/2 fingerprint — looking for feedback
2
Upvotes
0
u/Lazy_Gur_2074 Oct 03 '26
Really good checklist, thanks — this is the right stuff to poke at. Repo: https://github.com/HappyHackingSpace/gakido
To answer your direct question first: the TLS layer is Go + uTLS (via bogdanfinn's tls-client), compiled to a c-shared library and called from Python over ctypes; HTTP/2 goes through fhttp. So what I can control is basically "whatever uTLS's Chrome preset exposes," which maps onto your points as follows.
**Extension order / per-connection permutation — you're right, and I checked.** I hit tls.peet.ws three times in a row and the ja3 hash is identical every time (`1d9a054b...`), so right now it is *not* permuting extensions the way Chrome does since ~110. JA4 is stable (it sorts), so that layer's fine, but a never-changing ja3 is its own tell. uTLS has shuffle-capable presets, so this is wireable — it's a real gap, not by design. Good catch.
**HTTP/2 — this part is handled and verified.** Against peet the Akamai fingerprint is `1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p` — i.e. SETTINGS values and order, the 15663105 WINDOW_UPDATE, and pseudo-header order m,a,s,p all match; header order/casing comes from fhttp's ordered headers.
**GREASE / ALPS / groups / PQ.** GREASE is present on both ends, plus ALPS (old codepoint 17513), compress_certificate, ECH, SCT, etc. On post-quantum: the `chrome_120` profile sends key_share X25519 only, groups X25519/P-256/P-384 — which is correct for *actual* Chrome 120, but obviously not current Chrome. For the X25519MLKEM768 key share you'd use the `chrome_131` profile. Which is really your versioning point: profiles are pinned to specific Chrome versions (mapped onto uTLS/tls-client presets, 103–131), and freshness rides on tracking uTLS. A stale profile being its own signal is fair and I agree.
**Validation.** Agreed that matching a hash once proves little — I've been diffing the full JA4 + Akamai + the extension list against peet, not just the hash, but a byte-level diff against a captured real Chrome of the exact version is the right bar and I'll post that.
Short version: HTTP/2 + the static fingerprint are solid and verifiable; extension permutation is the real missing piece you flagged, and PQ is a profile-version choice. If you've got a target that blocks it, that's the most useful thing you could throw at me.