Skip to content

security: HTTP loader forwards custom auth headers (API keys) to cross-host redirect targets #154

Description

@robbyt

Summary

The HTTP script loader builds its http.Client with no CheckRedirect policy, so custom headers set via WithHeaderAuth(...) (e.g. X-API-Key) are re-sent on redirects to any host. Go's stdlib strips Authorization, Cookie, and WWW-Authenticate on cross-host redirects but does not strip arbitrary custom headers, so a configured API key can leak to a redirect target the operator never intended.

Root cause

platform/script/loader/fromHTTP.go: NewFromHTTPWithOptions (~L194-226) constructs the client without setting CheckRedirect, and GetReader (~L234-275) applies the configured Authenticator headers to the initial request. Default redirect handling then replays the custom headers on every hop.

Reproduction (confirmed)

Loader configured with WithHeaderAuth(map[string]string{"X-API-Key": "SECRET123"}), fetching https://scripts.example.com/x.risor. The host returns 302https://attacker.example/. The client re-sends X-API-Key: SECRET123 to attacker.example. In the same run, an Authorization header set via WithBearerAuth was stripped by Go — only the custom header leaked.

Trigger vectors: a compromised or malicious script host, a MITM on a plain-http URL, or a compromised CDN in front of the origin.

Impact

High — credential disclosure. Any caller using WithHeaderAuth (the documented way to pass API keys to a script endpoint) can leak that key to any host the endpoint redirects to.

Fix

Set client.CheckRedirect to drop auth and custom headers when the redirect target host differs from the original, or refuse cross-host redirects. Equivalently, re-apply the Authenticator only on same-origin redirects and strip the headers it added on cross-origin hops. Add tests asserting the custom header is absent on a cross-host redirect and present on a same-host one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions