Re: [whatwg/fetch] Drop developer-controlled Authorization header on cross-origin redirects (#944)

At the (very real) risk of mentioning what people already know, here is some additional information that might be helpful.

A similar problem was reported against [curl](https://curl.se/) as [CVE-2018-1000007](https://nvd.nist.gov/vuln/detail/CVE-2018-1000007) (a low severity vuln), which [they fixed](https://curl.se/docs/CVE-2018-1000007.html) in [v7.58.0](https://curl.se/changes.html#7_58_0) by dropping the `Authorization` header value when redirected to a different host.

Similarly, the popular Python HTTP client [Requests](https://docs.python-requests.org/en/master/) will [drop the `Authorization` header values](https://docs.python-requests.org/en/latest/user/quickstart/#custom-headers) "if you get redirected off-host".

Likewise the GO-language [http client](https://golang.org/pkg/net/http/#Client) drops the `Authorization` header on redirection to a different site.  The http library seems to use a slightly different algorithm when deciding when to drop sensitive headers.

That said, this behaviour is not universal: there are clients that (like Fetch API with `credentials: "include"`) will always include the `Authorization` header when redirected.  Similarly, I was unable to find a document describing dropping the `Authorization` header on redirection as security "best practice".  This seems to have grown somewhat organically.

Beyond the security implications, there may be some non-security related problems if the `Authorization` header is not dropped when redirected to a different host.  This is because the redirected host might not be authorised in "the same way" (e.g., the same realm).  There's no guarantees that the same username+password (or bearer token, or ...) will work.

Including the `Authorization` can also break otherwise working solutions.  Since the server issuing the redirection cannot (in general) influence the `Authorization` header the client presents after being redirected, a popular choice is to authorise the subsequent request by embedding a token within the `Location` URL.  If the client, when following the redirection, includes the same `Authorization` header value then the target service will receive two authorisation: the URL-embeded token and the `Authorization` header value.  An example of this is [dynafed](https://lcgdm.web.cern.ch/dynafed-dynamic-federation-project) when configured to mediate access to some S3 storage.  It will react to a GET request (from an authorised client) by generating a pre-signed URL, returning this URL as a redirection.  If the client also presents the Dynafed credential (an `Authorization` header) to the S3 endpoint then the pre-signed URL will not work, as the S3 endpoint favours the `Authorization` header value over the URL-embedded token.

My own use-case is somewhat similar.  On receiving a GET request, [dCache](https://www.dcache.org/) will generate a single-use bearer token to authorise a specific file transfer and respond with a redirection to a URL that embeds this token in the URL.  We currently support both encrypted (with TLS) and unencrypted data transfers.  We feel there are situations where this is acceptable to send the single-use bearer token over an unencrypted connection; however, this becomes problematic if the client sends a long-lived credential.  Using only TLS protected redirection would be possible if we had a reliable way to detect web-browsers using the Fetch API.

If I may venture an opinion, "Atomic HTTP redirect handling" is a stated goal of Fetch, which places the onus on the API (and the web-browser implementations) to "do the right thing".  The current behaviour for `credentials: 'include'` seems to go against perceived security best practice and would seem to have the possibility to break (seemingly) valid use-cases.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/944#issuecomment-831893666

Received on Tuesday, 4 May 2021 12:12:00 UTC