From 464777884b2b799e398989a3e033c8cc412782d0 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Fri, 19 Jun 2026 08:07:48 +0200 Subject: [PATCH] fix(toolbox-ng): H1 response-header timeout on the uTLS transport + changelog 0.1.6 (ref #662) --- .../secubox-toolbox-ng/cmd/sbxmitm/uchrome.go | 16 ++++++++++++++++ packages/secubox-toolbox-ng/debian/changelog | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/packages/secubox-toolbox-ng/cmd/sbxmitm/uchrome.go b/packages/secubox-toolbox-ng/cmd/sbxmitm/uchrome.go index a8b7b9f1..f6829192 100644 --- a/packages/secubox-toolbox-ng/cmd/sbxmitm/uchrome.go +++ b/packages/secubox-toolbox-ng/cmd/sbxmitm/uchrome.go @@ -63,6 +63,11 @@ var chromeHello = utls.HelloChrome_Auto const ( upstreamDialTimeout = 10 * time.Second upstreamHandshakeTimeout = 10 * time.Second + // upstreamResponseTimeout bounds write-request + read-response-HEADERS on the + // HTTP/1.1 path (mirrors stdlib http.Transport.ResponseHeaderTimeout): without + // it, an origin that completes TLS then never replies pins a worker goroutine + // forever. Cleared before body streaming so large/slow downloads aren't cut. + upstreamResponseTimeout = 30 * time.Second ) // uchromeTransport is an http.RoundTripper that, for every request, opens a @@ -240,6 +245,16 @@ func (b *h2BodyCloser) Close() error { // request and reading the response with the stdlib. The response body is wrapped // so that closing it closes the conn — single-use, no pooling, no fd leak. func roundTripH1(uconn *utls.UConn, req *http.Request) (*http.Response, error) { + // Bound write-request + read-response-HEADERS: an origin that completes the + // TLS handshake then stalls would otherwise pin this goroutine forever + // (the http.Client.Timeout in the caller does NOT reach a custom + // RoundTripper's raw conn I/O). Honour the request context deadline if it is + // sooner; clear the deadline before returning so body STREAMING isn't capped. + deadline := time.Now().Add(upstreamResponseTimeout) + if d, ok := req.Context().Deadline(); ok && d.Before(deadline) { + deadline = d + } + _ = uconn.SetDeadline(deadline) // Write the request over the conn. req.Write emits a valid origin-form // HTTP/1.1 request (RequestURI was cleared by the caller). if err := req.Write(uconn); err != nil { @@ -251,6 +266,7 @@ func roundTripH1(uconn *utls.UConn, req *http.Request) (*http.Response, error) { uconn.Close() return nil, fmt.Errorf("utls h1 read: %w", err) } + _ = uconn.SetDeadline(time.Time{}) // headers in: don't cap body streaming resp.Body = &h1BodyCloser{ReadCloser: resp.Body, conn: uconn} return resp, nil } diff --git a/packages/secubox-toolbox-ng/debian/changelog b/packages/secubox-toolbox-ng/debian/changelog index 4d2ca7bb..e153567c 100644 --- a/packages/secubox-toolbox-ng/debian/changelog +++ b/packages/secubox-toolbox-ng/debian/changelog @@ -1,3 +1,16 @@ +secubox-toolbox-ng (0.1.6-1~bookworm1) bookworm; urgency=medium + + * anti-bot: present a Chrome TLS fingerprint upstream via uTLS (HelloChrome_Auto) + + h2-over-uTLS, defeating JA3/JA4 fingerprinting (DataDome etc.) WITHOUT + splicing — cert chain + hostname verification stays ON (manual verifyUConn). + * stop downgrading Accept-Encoding (forward the browser's verbatim); decode/ + inject/re-encode brotli + zstd so injection coverage survives the full AE. + * h1: bound write+response-header read (ResponseHeaderTimeout-equivalent) so a + stalling origin can't pin a worker. First vendored deps (utls/brotli/zstd/ + x-net), offline arm64 build via -mod=vendor. (ref #662) + + -- Gerald KERMA Thu, 19 Jun 2026 09:00:00 +0000 + secubox-toolbox-ng (0.1.5-1~bookworm1) bookworm; urgency=medium * ad-stats: record ad-block metrics again (frozen since the #662 cutover) —