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]

Reply via email to