fetch icon indicating copy to clipboard operation
fetch copied to clipboard

Redirect loop handling not discussed

Open simon-friedberger opened this issue 2 years ago • 5 comments

What is the issue with the Fetch Standard?

This came up in the context of HTTPS upgrades. It was discussed in the initial explainer here: https://github.com/dadrian/https-upgrade/blob/main/explainer.md#proposed-behavior-change

Redirects to HTTP: If a navigation would result in a redirect to HTTP, that redirection should also get upgraded to HTTPS. This applies both to navigations that are initially to HTTP URLs which get upgraded to HTTPS (and then redirected to an HTTP URL) and to navigations that are initially to HTTPS URLs that are redirected to HTTP. If these upgrades result in a redirect loop (for example, https://http.badssl.com/ redirects to http://http.badssl.com/, which would be upgraded to https://http.badssl.com/, and so on), this should be considered a failed upgrade.

@annevk suggested that this should be covered by the 20 redirect limit and asked for a separate issue here.

An example for which we have an issue is a page which redirects after a timeout. (www.bom.gov.au) gets upgraded and then redirects to (http://www.bom.gov.au/akamai/https-redirect.html) which redirects using window.location.replace after 10 seconds. In this case relying on the 20 redirects limit would take over 3 minutes.

The spec does state that requests can be exempt in an "implementation defined way". Chrome seems to have explicit loop detection: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/chrome/browser/ssl/https_upgrades_interceptor.cc#519

Of course, the example above also uses a JS based redirect so it may be impossible to define a satisfying solution here.

simon-friedberger avatar Feb 22 '24 12:02 simon-friedberger

It seems there's two ways we could go about this:

  1. We use the existing "redirect count" primitive of requests, but make HTML also check and increment it for certain cases. Since HTML creates new requests in those cases you probably have to copy the value over to the new request. And it should probably all be limited to when we're doing an HTTPS upgrade.
  2. We introduce a new primitive solely for HTTPS upgrades. In this case we could either do loop detection or a limit. I think going with a limit again is more consistent, but perhaps there's rationale for not doing that?

annevk avatar Apr 09 '25 09:04 annevk

Chrome's logic effectively uses both the existing limit and an additional loop detection. The upgrade navigation is still subject to normal redirect limits, but the loop detection can also fail the upgrade much sooner. We found early failures in the upgrade path to be practical.

That said, I don't think we should address JS redirects here. The current proposal was intended with only server side redirects in mind.

meacer avatar Apr 17 '25 21:04 meacer

@meacer according to @simon-friedberger you all also look at <meta http-equip=refresh> and the like. Is that not the case?

I also realized that it's not quite as simple as I made it out above. In particular if you look at <meta http-equiv=refresh> you have to forward the "redirect count" to new requests.

annevk avatar Apr 22 '25 13:04 annevk

@meacer according to @simon-friedberger you all also look at <meta http-equip=refresh> and the like. Is that not the case?

We don't have any specific logic for meta redirects. Something like <meta http-equip=refresh content='0'> shouldn't trigger a redirect loop in Chrome. So yeah, I think I'd count any redirect that happens after the page load as out of scope for this change.

meacer avatar Apr 26 '25 00:04 meacer

I see, I think I got confused by this comment from @simon-friedberger: https://github.com/whatwg/fetch/pull/1655#issuecomment-1943496127. That suggested "redirect-like" behavior would also count.

Did someone analyze whether an attacker could use HTTP-redirect loop detection as some kind of side channel?

I understand why we'd want to bail out early for an end-user-facing feature so modulo the attacker concern it makes sense to me to define the HTTP-redirect loop detection and use it for HTTPS upgrades. It seems we could build this on top of request's URL list concept?

annevk avatar Apr 28 '25 12:04 annevk