-
Notifications
You must be signed in to change notification settings - Fork 337
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
Allow HTTP scheme fetches to make CORS preflight for navigations #1785
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the idea with this PR is that <var>makeCORSPreflight</var>
variable is really closer to "makeCORSPreflight if needed", and can be set to true because it won't trigger preflights except for when requests otherwise demand them by using an unsafe method or request header?
But I think this PR will have side effects on other requests that would suddenly start triggering preflights, when they shouldn't. For example:
fetch("https://google.com", {method: 'GET', mode: 'no-cors', headers: {'Content-Type': 'application/json'}})
... uses an unsafe request header, which would ordinarily trigger a preflight, but for the no-cors
mode which never sends preflights1. I think this PR would change that, and preflights would be sent for these kinds of no-cors
requests, at the very least.
Another way to achieve this is to set the use-CORS-preflight flag on the relevant kinds of navigation requests that we want to subject to preflights. Unfortunately, that wouldn't integrate cleanly with "Main fetch" today, given how mode=navigate
fetches are handled before we consider the use-CORS-preflight flag, just a few conditions down.
So maybe the best option is to modify scheme fetch to only turn a false "makeCORSPreflight" to true if the request mode is navigate (instead of unconditionally as you're doing now)?
Footnotes
-
This is because scheme fetch is invoked from the no-cors path, which today calls HTTP fetch without the
makeCORSPreflight
variable set to true, so we would never even test the method or request headers. ↩
@domfarolino First of all, thank you so much for the thoughtful review!
Yes, this is my understanding of HTTP Fetch Step 4.1, which only issues the preflight if the request has attributes (method or headers) that are not CORS-safelisted (or if the use-CORS-Preflight flag is set); otherwise, it proceeds as normal (the path navigation takes today). I'm happy to rename it, but my instinct is to touch as little as possible.
I agree that this is not ideal. It would also create some confusion around when exactly CORS is supposed to be checked in the request lifecycle. Since it already happens in one path that the navigation fetch will definitely reach (HTTP fetch), I'd like to re-use that logic if possible.
This seems great, and more narrow. There's also precedent for inspecting the request mode after that main switch. I will go ahead and make that change! |
dda4b4f
to
8d27e59
Compare
I think the current approach is at least safe, and avoids the scary side effects pointed out further above. I think it'd be great to get a gut check from @annevk on this now. |
8d27e59
to
cb0d8ad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-editor LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these need to be separate steps as this is confusing. (Though not in the way you had before. Initialize the boolean in one step, then make the HTTP fetch call.) It also misses a bunch of markup for the various concepts.
Then, I wonder if we need to identify these preflights are for navigations in some respect to the server as they might well want to enforce different policies between subresources and navigations. Perhaps Sec-Fetch-Dest suffices for that. Ideally we find something here that is unified with Private/Local Network Access.
I would also like to research why we identify whether a request needs a preflight in two separate locations currently. I can't remember and having now read it a few times I don't understand. Any chance you want to dig into blame? If not I'll get to it in due course.
The name makeCORSPreflight also seems rather confusing as it doesn't actually mean a CORS preflight will be made.
Thanks very much @annevk for the excellent review.
I agree and I'll make that change.
Strongly support this.
Happy to take a crack at it as well.
I defaulted to making as few changes as possible, although I completely agree (and that name certainly contributed to a couple extra hours of work trying to parse the spec). With your invitation I am happy to rename it—how do you feel about allowCORSPreflight? |
(Sec-Fetch-Mode will be set to " |
Oh, you're right, thanks for the link. I think It should also apply to PNLA links. |
But just to be clear, this PR allows CORS for non-top-level navigations too, right? |
Yep. This would allow CORS for any fetch with the |
cb0d8ad
to
6847cac
Compare
This allows navigations to make CORS preflight requests, if the navigation contains a request that is not safelisted. Navigation does not (yet) provide APIs for non-safelisted requests; this update to the fetch spec is a prerequisite for HTML spec changes that might add those APIs (i.e. PUT method support in forms).
6847cac
to
060cc1d
Compare
Made Anne's suggested updates: split out "is this for navigation" into its own variable, and renamed I don't think there are any updates required for |
This allows navigations to make CORS preflight requests, if the navigation contains a request that is not safelisted. Navigation does not (yet) provide APIs for non-safelisted requests; this update to the fetch spec is a prerequisite for HTML spec changes that might add those APIs (i.e. PUT method support in forms).
No web platform tests or MDN updates are included, as no changes to browser functionality are required by this update alone.
This change supports the work outlined in this WHATWG Issue #3577 comment.
(See WHATWG Working Mode: Changes for more details.)
Preview | Diff