feat(cli): TLS/HTTP2 fingerprint hardening via tls-client #40

Merged
starkSV merged 2 commits from feat/cli-tls-fingerprint-hardening into main 2026-07-31 12:18:56 +05:30

2 commits

Author SHA1 Message Date
Shekhar Vaidya
78be837a4a docs: explain the Sentinel WAF saga, retire completed plans, commit the needs-warming spec
PROGRESS.md and CLAUDE.md now document the full investigation: three
weekly checkpoints confirming the backend's direct link-fetch is
100% dead, the crowdsourced CLI-contribution cache carrying the real
load (286 accepted, 0 rejected), the two merged backend fixes
(lockdown TTL, /proxy product_id validation), and the CLI TLS
fingerprint hardening in this branch (functionally verified, not yet
validated against the Sentinel-rejection-rate trend).

Removed two plan+spec pairs under docs/superpowers/ (the original CLI
build plan and the telemetry/update-check plan+design) -- both fully
shipped, redundant with PROGRESS.md's own record of what happened.

Committed docs/superpowers/specs/2026-07-13-needs-warming-design.md
for the first time -- it's been sitting untracked in the working tree
for weeks. Unlike the two removed docs, this one is a live, unbuilt
proposal (a public page surfacing which products are currently
Sentinel-locked with no cached fallback), not completed work, so it's
kept and now tracked in the backlog instead of discarded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-31 12:08:38 +05:30
Shekhar Vaidya
9e22cd8bf8 feat(cli): TLS/HTTP2 fingerprint hardening via tls-client
Three checkpoints over 17 days confirmed a stable ~20% Sentinel
rejection rate on the CLI's own requests, despite running from
residential IPs specifically to avoid ASN-based blocking. That
persistence points at TLS ClientHello fingerprinting as an additional
signal: Go's stdlib crypto/tls produces a handshake that looks nothing
like a real browser, independent of IP or headers.

Swaps the CLI's HTTP transport (session setup, SKU lookup, download
link fetch, eval link resolution) from net/http to
github.com/bogdanfinn/tls-client, which wraps utls with a maintained
Chrome browser profile (TLS + HTTP2 fingerprint together, not just
TLS -- a browser-consistent one without the other is its own tell).
Bumped msUA's claimed Chrome version to 133 to match the chosen
profile, since a mismatched UA vs. TLS fingerprint is itself
detectable.

The custom simpleCookieJar is gone -- tls-client provides its own
cookie jar. fetchEvalLinks got the same treatment for consistency,
even though the Eval Center path isn't currently blocked.

Verified: go build/vet/test all pass, and a live end-to-end run
(msdl --id 3262 --lang English) returned a real signed download link
and successfully contributed it back to the shared cache. That proves
the flow still works functionally through the new client -- it does
NOT prove the fingerprint theory, since the old client already
succeeded ~80% of the time. The real test is watching the Sentinel-
rejection-rate telemetry over a comparable multi-day window after
this ships.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-31 12:02:44 +05:30