zeroshade opened a new issue, #2089: URL: https://github.com/apache/iceberg-go/issues/2089
### Problem `sessionTransport.RoundTrip` (catalog/rest/rest.go:251-338 on main @ dd935d8) adds session credentials to every request it sends: the `header.*` / `WithHeaders` defaults (rest.go:257-268), the `authManager` header, typically `Authorization: Bearer <catalog token>` (rest.go:276-293), and the SigV4 signature (rest.go:295). The catalog `http.Client` is built with no `CheckRedirect` (rest.go:1074), so the default redirect policy applies and each redirect hop goes back through `RoundTrip`. If the catalog responds with a 3xx to a different host, that host receives the catalog bearer token and any `header.*` values. Go's stdlib protection does not apply here. `Client.do` snapshots the headers of the initial request before the first send (`makeHeadersCopier`, net/http/client.go:772-776). On each redirect it copies that snapshot and drops `Authorization`, `Www-Authenticate`, `Cookie`, `Cookie2`, `Proxy-Authorization` and `Proxy-Authenticate` when the destination hostname is neither the initial hostname nor a subdomain of it (`shouldCopyHeaderOnRedirect`, client.go:1017-1039, applied at client.go:700-705 and 822-840). Our credentials are not in that snapshot because the transport adds them per hop inside `RoundTrip`, after the client has done its stripping, so the stdlib check never sees them. Custom `header.*` values are never treated as sensitive by stdlib, so they would be forwarded either way. ### Reproduction I ran a throwaway internal test against main. Catalog at `http://127.0.0.1:<p1>`, `/v1/redirect` returns 307 to `http://localhost:<p2>/landing` (different hostname). Catalog built with `WithOAuthToken("SECRET-CATALOG-TOKEN")` and `WithAdditionalProps({"header.X-Api-Key": "SECRET-API-KEY"})`, then `cat.cl.Do(GET /v1/redirect)`. - Control, plain `http.Client` with `Authorization` set on the request before `Do`: the redirect target received `Authorization=""` (stripped by stdlib). - Catalog client: the redirect target received `Authorization="Bearer SECRET-CATALOG-TOKEN"` and `X-Api-Key="SECRET-API-KEY"`. Expected: neither value reaches a host other than the configured catalog origin. ### Other implementations - pyiceberg uses `requests`, whose `Session.rebuild_auth` drops `Authorization` when a redirect changes host. ### Proposed fix In `RoundTrip`, apply the auth-manager header and the `header.*` defaults only when the request's scheme, host and effective port match the configured catalog origin, the same check #1999 adds for SigV4 (`signingOrigin` / `sameOrigin`). Reuse those helpers once #1999 lands. Add a two-host regression test like the one above that asserts the target receives neither header. Alternatively, a `CheckRedirect` that refuses cross-origin redirects would close it more bluntly. ### Related - #1999 adds the same-origin guard for SigV4 signing only. - #2060 moves SigV4 into a pluggable `RequestSigner`. The origin check should stay in core `RoundTrip` so it covers both the signer and the auth/header path. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
