Skip to content

Provider HTTP clients follow redirects to subdomains and other ports with the key attached - #1908

Draft
ZeroPoint95 wants to merge 3 commits into
devfrom
zeropoint95/1896-provider-http-clients-follow-redirects-t
Draft

ZeroPoint95 wants to merge 3 commits into
devfrom
zeropoint95/1896-provider-http-clients-follow-redirects-t

Conversation

@ZeroPoint95

Copy link
Copy Markdown
Collaborator

Changes

  • Every client that carries the configured provider key now follows only same-origin redirects: a redirect to another port, a subdomain or an unrelated domain of the configured host is refused with an error naming the target host, never sent the key, while same-origin redirects keep working. The rule is one shared stdlib-only package, internal/redirect (Policy + Guard), applied at all seven key-carrying construction sites: the provider request and stream clients, the media client, the lane sheet fetcher, the config service probes, the catalog fetch and the router's catalog fetch.
  • A refused redirect is a typed error the provider dispatcher returns immediately instead of re-asking the same origin until the deadline, so a stop stays visible to the person; the redirect-chain cap matches Go's stdlib boundary exactly — on an endless same-origin loop both the stock client and the product policy send exactly ten requests and stop with 'stopped after 10 redirects'.
  • Regression coverage (internal/provider/zz_issue_repro_test.go, deterministic, no DNS or model) asserts that the subdomain, other-port and unrelated-domain redirects each fail naming the target with nothing reaching it, and that a same-origin 307 completes end to end; a changelog entry for Provider HTTP clients follow redirects to subdomains and other ports with the key attached #1896 is included.
  • Final change: 11 files, +379/−7.

Closes #1896.

Validation

  • Passed locally: cd . && go test -count=1 -run TestIssueReproRedirectForwardsKey -v ./internal/provider/ 2>&1 | grep -E '^(=== RUN|--- PASS|--- FAIL|PASS|FAIL|ok)'; echo "REPRO-EXIT=${PIPESTATUS[0]}".
  • Passed locally: cd . && go test -count=1 -run TestProofParityStockVsPolicyEndlessLoop -v ./internal/redirect/ 2>&1 | grep -E '^(=== RUN|--- PASS|--- FAIL|PASS|FAIL|ok)'; echo "PARITY-EXIT=${PIPESTATUS[0]}".
  • Passed locally: cd . && go test -count=1 ./internal/namelaw/ 2>&1 | tail -2; echo "NAMELAW-EXIT=${PIPESTATUS[0]}"; make changelog-check 2>&1 | tail -2; echo "CHANGELOG-EXIT=${PIPESTATUS[0]}".
  • Proof · 3 of 3 claims shown locally. GitHub CI is checked after publishing.
  • ✓ The Provider HTTP clients follow redirects to subdomains and other ports with the key attached #1896 regression holds end to end on HEAD 7f7c441: a 307 to a subdomain, to another port of the configured host, or to an unrelated domain each fails the completion with the typed refusal naming the target host, and the redirect target receives no request at all (Authorization included); a same-origin 307 completes and reaches the landed path. The chain-cap dispute between the review commit and the later re-fix is settled: the stdlib default refuses at len(via) >= 10 (checked before the next request is built), and the product policy at HEAD matches it exactly.
  • ✓ Every check on the committed tree is green: the internal/redirect unit suite, the full provider/catalog/config/router touched-package suites, the namelaw gate, the changelog gate, gofmt, go build and go vet. Nothing in the changed set is red, and the tree is clean at HEAD.
  • ✓ Inspection confirms every claim about where and how the rule is applied: all seven key-carrying construction sites carry redirect.Policy or redirect.Guard (provider request client client.go:244, stream client client.go:245, media.go:176 with connection sharing the guarded client, lanes.go:900, config/sources.go:570, catalog/catalog.go:1207, router/catalog.go:99 — whose fetchCatalog does set Authorization: Bearer from apiKey, called as fetchCatalog(baseURL, apiKey, client) at catalog.go:64); Guard composes a caller's CheckRedirect and preserves Transport/Timeout; dispatch.

by codeaf factory

Factory-Approval: evt_f69a14bd @ZeroPoint95 7f7c441

ZeroPoint95 and others added 3 commits October 22, 2026 21:49
Every client that carries the configured provider key now shares one redirect
rule: follow a redirect only when the target keeps the original request's
scheme, hostname and effective port, and refuse any other redirect with an
error naming the target host. Go's default policy had forwarded Authorization
to a redirect that stayed on the same hostname (including another port) or
moved to a subdomain of it. The refused redirect is typed so the provider
dispatcher stops at once instead of re-asking the same origin until the
deadline.

Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
Assisted-by: CodeAF (deepseek-v4-flash-latest)
Policy refused a chain one hop before Go's own 10-redirect cap, and its
message named a depth it never reached. Refuse exactly where the standard
library stops, and give the boundary-adjacent chain its own assertion.

Assisted-by: CodeAF (deepseek-v4-flash-latest)
Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
The review commit 6731c37 moved the chain cap one hop looser than both
the write stage's original and the stdlib default: net/http's
defaultCheckRedirect refuses at len(via) >= 10 (client.go:845), checked
before the next request is built, so the stock client sends exactly ten
requests on an endless same-origin loop while len(via) > 10 let an
eleventh out. Restoring >= 10 matches the stdlib depth exactly; the unit
test now pins refusal at ten requests in the chain and follow at nine.

Verified empirically: on an endless same-origin 307 loop, both the stock
default client and a client using Policy send exactly ten requests and
stop with "stopped after 10 redirects" (proof harness since removed).

Assisted-by: CodeAF (deepseek-v4-flash-latest)
Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
@santoshkumarradha
santoshkumarradha force-pushed the zeropoint95/1896-provider-http-clients-follow-redirects-t branch from 7f7c441 to 5fb5c6f Compare October 24, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provider HTTP clients follow redirects to subdomains and other ports with the key attached

1 participant