Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS upgrades proposal #1655

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

carlosjoan91
Copy link
Contributor

@carlosjoan91 carlosjoan91 commented May 11, 2023

(See WHATWG Working Mode: Changes for more details.)


Preview | Diff

Copy link
Member

@mikewest mikewest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments:

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@carlosjoan91 carlosjoan91 marked this pull request as ready for review June 22, 2023 20:44
@carlosjoan91 carlosjoan91 requested a review from annevk June 22, 2023 20:46
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
Copy link
Collaborator

@yoavweiss yoavweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more nits. Otherwise, non-authoritiative LGTM

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@christhompson
Copy link

Thanks for all the help with editing this Yoav!

@annevk I think this PR should be in a good place now if you have time to take a look.

@christhompson
Copy link

I'm not sure why the CI build is failing -- the bikeshed error FATAL ERROR: Spurious / in <a> isn't reproducible when running make local locally.

@annevk
Copy link
Member

annevk commented Jul 25, 2023

It would help a lot if this was rebased as a single commit describing the changes it is making. (I attempted to rebase locally against main in order to address the CI issue but immediately ran into a merge conflict.)

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. I've done an initial review that mainly focuses on editorial issues.

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@meacer
Copy link

meacer commented Aug 2, 2023

annevk: Friendly ping

@christhompson
Copy link

Pinging again -- let us know if there are any remaining concerns.

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay here. I blame European summer.

So this still applies:

It would help a lot if this was rebased as a single commit describing the changes it is making. (I attempted to rebase locally against main in order to address the CI issue but immediately ran into a merge conflict.)

In particular it seems Build (CI) hasn't even run for this change, which is a problem.

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@meacer
Copy link

meacer commented Sep 27, 2023

Thank you for the review! Rebased into a single commit, but the Build still doesn't seem to be running. I get a "1 workflow awaiting approval" warning above it, so not sure if a maintainer needs to specifically allow it to run.

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@annevk
Copy link
Member

annevk commented Sep 29, 2023

Hey @meacer, thanks for the update. I left a bunch of inline comments including on some of the old threads. I think it would be good for you to resolve all the threads you consider resolved at this point and leave those open you still have questions on. Generally instead of writing "Done" hitting "Resolve conversation" is fine. That also helps the reviewer to know what to focus on. Also if you want any kind of live feedback I'd recommend https://whatwg.org/chat.

@meacer
Copy link

meacer commented Sep 29, 2023

@annevk Apologies for the comment noise. I'm not the original author of the PR so I don't have the "Resolve conversation" option. I asked Carlos to resolve most of them (thanks Carlos!). I'll need to think about the service worker parts before I respond on the remaining threads. Thank you again.

@meacer meacer force-pushed the httpsupgrades branch 2 times, most recently from 54a3d49 to 74247e3 Compare October 24, 2023 05:56
@meacer
Copy link

meacer commented Nov 1, 2023

@annevk I believe my last commit addresses all your comments. Could you please take a look when you have a chance? Thanks.

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly nits and still the fundamental question about why you're patching HTTP fetch rather than HTTP-network fetch.

Having a commit message somewhere explaining the rationale behind the changes would go a long way.

fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
fetch.bs Outdated Show resolved Hide resolved
@simon-friedberger
Copy link

@simon-friedberger are you asking for a note? The current text already requires it.

Thanks @annevk, that is indeed what I was looking for. If you don't mind, could you point me at the right text? I checked again but still cannot find it.

@annevk
Copy link
Member

annevk commented Feb 13, 2024

It's subtle, but because only the scheme is changed the port remains unchanged. And when the scheme is "http" the port is either null or a non-80 integer (due to the URL parser). And when you go make a request and the scheme is "https" and the port is null, it uses 443. (This subtle behavior happens in multiple places though so I'm a bit hesitant to add notes all over, but maybe there's a way to make it work well.)

@simon-friedberger
Copy link

The explainer touched on loop handling behavior:

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.

I don't see this in the PR and this WPT implies that the query string should be part of the data used for detecting loops. Should this be part of the spec and not just the test?

Also, I guess that the fragment should not be part of such a check, correct?

@annevk
Copy link
Member

annevk commented Feb 13, 2024

The only thing I don't see is "redirect loop" and I also don't see that being tested. However, I don't think we should add that as we already have a limit on 20 redirects that should suffice.

@simon-friedberger
Copy link

For context, Chrome seems to have explicit loop detection: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/chrome/browser/ssl/https_upgrades_interceptor.cc#519

The WPT is upgrading with new URL("http://{{host}}:{{ports[https][0]}}/fetch/api/resources/redirect.py?location=" + … which will trigger loop detection unless the query string is included.

What should happen on pages which redirect after a timeout like (www.bom.gov.au) which gets upgraded and then redirected to (http://www.bom.gov.au/akamai/https-redirect.html) which redirects using window.location.replace after 10 seconds. Using the 20 redirects limit would take over 3 minutes to get to the actual page.

@mozfreddyb
Copy link
Collaborator

I believe there is a disconnect about the redirect loops between what @annevk and @simon-friedberger understood.

The issue isn't reaching the maximum of allowed redirects, but whether a browser should look at previous URLs in the redirect chains to stop upgrading. E.g., for a page that supports HTTPS but redirects back to HTTP.

Specifically, how "far" does the browser look back? All 20? Which information does the browser use to consider something a loop? Just the domain? The site? With URL parameters?

If all browsers have explicit "loop breakout logic", we should specify it.

@annevk
Copy link
Member

annevk commented Feb 14, 2024

I thought I understood, but now various kinds of redirects are getting conflated and it's getting confusing. I'm not sure this PR is the best place to have that discussion. I don't think we should have loop detection for HTTP or (specified) internal redirects. Website-driven navigations that look like redirects are not covered here. If they should be that should also be discussed in a new issue.

@simon-friedberger
Copy link

Isn't there a problem specific to HTTP upgrades, though? If a website has a redirect loop, sure, the website needs to fix it. But if there is a redirect loop in the browser because it is upgrading HTTP to HTTPS it needs to be fixed in the browser. Anyway, just let me know if I should file a separate issue, please!

@simon-friedberger
Copy link

simon-friedberger commented Mar 20, 2024

It's subtle, but because only the scheme is changed the port remains unchanged. And when the scheme is "http" the port is either null or a non-80 integer (due to the URL parser). And when you go make a request and the scheme is "https" and the port is null, it uses 443. (This subtle behavior happens in multiple places though so I'm a bit hesitant to add notes all over, but maybe there's a way to make it work well.)

Should this behavior be changed and custom ports be exempt from upgrades? Configurations which use the same port for HTTP and HTTPS seem rare (I don't have any data). In some cases this does cause bugs like the one linked above: aio-libs/aiohttp#8065 & python/cpython#109765

@mozfreddyb
Copy link
Collaborator

@meacer Are you still working on this? Have Chrome's plans for this changed somehow?

@annevk annevk added the agenda+ To be discussed at a triage meeting label May 31, 2024
@past past removed the agenda+ To be discussed at a triage meeting label Jun 6, 2024
@meacer
Copy link

meacer commented Jun 11, 2024

@meacer Are you still working on this? Have Chrome's plans for this changed somehow?

Apologies for my late reply. Chrome's plans for HTTPS Upgrades haven't changed. In fact HTTPS Upgrades are now enabled by default in Chrome, starting in Chrome 115. Therefore, this spec change is still a priority for us.

Regarding redirect loop detection: I don't think it's possible to break out of loops between https upgrades and http fallbacks without any sort of detection logic. The https://www.bom.gov.au/ example above is a good one where this is needed. Given that most browsers will need this, I agree it makes sense to add it to the spec.

@simon-friedberger
Copy link

It looks like there is a logic error in the fallback handling. This is inserted before the HSTS and HTTPS RR handling so a request will have its "is HTTPS upgrade" flag set and a downgrade will be attempted even if HSTS or HTTPS RR would have enforced HTTPS anyway.

@Dreamsorcerer
Copy link

Configurations which use the same port for HTTP and HTTPS seem rare (I don't have any data).

I would point out that it's actually quite complex to setup a server that supports this in most software (see for example: https://serverfault.com/questions/47876/handling-http-and-https-requests-using-a-single-port-with-nginx/). So, I'd agree this seems unlikely.

@meacer
Copy link

meacer commented Nov 26, 2024

Hello,

I made a few changes to this PR:

  1. Added an example for custom ports
  2. Added an example for redirect loops
  3. Moved the upgrade step after HSTS upgrades to avoid setting a fallback URL when an HSTS upgrade is done

(3) also makes the flow more in-line with the HTTPS Upgrades implementation in Chrome. Chrome does HTTPS upgrading before HSTS, but first checks if the URL would be upgraded by HSTS. If yes, it doesn't continue with the upgrade and lets HSTS handle the navigation.

This latest change should handle all of the concerns raised in the comment thread before. Please let me know if the latest diff looks good, thanks.

@meacer meacer force-pushed the httpsupgrades branch 2 times, most recently from 96b4288 to 043386a Compare November 26, 2024 21:04
@simon-friedberger
Copy link

@meacer If I am reading this correctly you are saying "don't upgrade custom ports, but we're not specifying it". Why not specify it? ISTM that there is too much going on under is exempted from upgrades in an [implementation-defined](...) way.

@meacer
Copy link

meacer commented Nov 26, 2024

@meacer If I am reading this correctly you are saying "don't upgrade custom ports, but we're not specifying it". Why not specify it?

That's fair. I think all implementations are going to have this exception, so I explicitly specify it now.

@simon-friedberger
Copy link

Afaict "HTTPS Upgrade" is the same as "HTTPS upgrade fallback URL" is non-null. Is this redundancy intentional? Algorithm 2.11.1 checks the latter but 2.11.2 checks the former which seems odd. Am I missing something?

@simon-friedberger
Copy link

I already filed an issue for redirect behavior a while ago: #1738

Only an example mentions it and it is fairly trivial:
http://a.com -> https://a.com -> http://a.com

There are plenty of common but more complicated cases like
http://a.com -> https://a.com -> https://www.a.com -> http://www.a.com

Chrome has implemented a quite thorough redirect URL list to detect arbitrarily complicated loops.
Anne suggested that this should simply be covered by the 20 redirect limit.

Some redirect detection should be standardized. The fact that we have WPTs for it is a good indicator that we want to align on the same behavior here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.