Skip to content

github: stop cross-host redirects to prevent bearer token leakage#4189

Open
evilgensec wants to merge 1 commit intogoogle:masterfrom
evilgensec:fix-cross-host-redirect-token-leak
Open

github: stop cross-host redirects to prevent bearer token leakage#4189
evilgensec wants to merge 1 commit intogoogle:masterfrom
evilgensec:fix-cross-host-redirect-token-leak

Conversation

@evilgensec
Copy link
Copy Markdown

@evilgensec evilgensec commented May 6, 2026

WithAuthToken wraps the Transport with a RoundTripper that unconditionally
injects Authorization: Bearer TOKEN on every RoundTrip call, including
intermediate calls that http.Client makes when following redirects.
Go's http.Client strips the Authorization header before building a
cross-host redirect request, but the wrapped Transport immediately
re-adds it, forwarding the token to every host in the redirect chain.

The GitHub API redirects certain endpoints to different hosts. Repository
archive downloads are redirected to codeload.github.com and release
asset downloads are redirected to objects.githubusercontent.com. Any
application that calls an endpoint that redirects cross-host, or that
accepts user-provided URLs, will leak its GitHub token to the redirect
destination.

Fix: add a CheckRedirect hook in WithAuthToken that returns
http.ErrUseLastResponse when the redirect target host differs from the
initial request host. This surfaces the 3xx to the caller instead of
following it, preventing token injection into cross-host requests. The
hook composes correctly with any CheckRedirect already set on the
underlying http.Client.

Same-host redirects continue to work as before.

New tests:

  • cross-host redirect does not leak token: verifies 302 is returned and
    the redirect destination does not receive the Authorization header.
  • same-host redirect is followed: verifies backward compatibility for
    same-host redirects.

Fixes #4190

WithAuthToken wraps the Transport with a RoundTripper that unconditionally
injects Authorization: Bearer TOKEN on every RoundTrip call, including
intermediate calls that http.Client makes when following redirects.
Go's http.Client strips the Authorization header before building a
cross-host redirect request, but the wrapped Transport immediately
re-adds it, forwarding the token to every host in the redirect chain.

The GitHub API redirects certain endpoints to different hosts. Repository
archive downloads are redirected to codeload.github.com and release
asset downloads are redirected to objects.githubusercontent.com. Any
application that calls an endpoint that redirects cross-host, or that
accepts user-provided URLs, will leak its GitHub token to the redirect
destination.

Fix: add a CheckRedirect hook in WithAuthToken that returns
http.ErrUseLastResponse when the redirect target host differs from the
initial request host. This surfaces the 3xx to the caller instead of
following it, preventing token injection into cross-host requests. The
hook composes correctly with any CheckRedirect already set on the
underlying http.Client.

Same-host redirects continue to work as before.

New tests:
- cross-host redirect does not leak token: verifies 302 is returned and
  the redirect destination does not receive the Authorization header.
- same-host redirect is followed: verifies backward compatibility for
  same-host redirects.

Fixes google#3386
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.

github: WithAuthToken leaks bearer token on cross-host redirects

1 participant