-
Notifications
You must be signed in to change notification settings - Fork 50
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
Do we want to allow web developers to add headers of the CONNECT request? #263
Comments
I'm not sure I understand the setup. I thought WebTransport would use ALPN. It seems to me that once ALPN is okay with a specific WebTransport identifier, everything after that is okay as it would be part of the protocol? |
True, the client must not start establishing a WebTransport session before receiving SETTINGS_ENABLE_WEBTRANSPORT. With that settings, is it OK to send arbitrary headers (as long as the request makes sense in the context of WebTransport over HTTP/3)? |
I think so. WebSocket and We should make this clear in the WebTransport specification (e.g., in a considerations for server implementers section) and hopefully devrel will also cover this extensively. |
I think from a privacy and security perspective this looks okay. We probably want to block request-body-header names too since although they wouldn't create security problems they'd be very confusing if set. I assume extensions will be able to read and modify the headers? I'm not sure what I feel about this from a design perspective. Is this something we're going to regret later? |
My personal intuition on this:
|
I guess this is about about session establishment as written down in https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3#section-3.3? So in theory that is post-ALPN so the server should know what is going on. However, I guess there is the concern servers might agree to the ALPN handshake but then handle the request in a normal endpoint (for authentication purposes and such), similar to what has been happening with WebSocket. I suspect we would never include cookies or HTTP authentication in this CONNECT request, unlike WebSocket? |
I'm not sure what ALPN specifically has to do here, since they both have ALPN of The CONNECT requests are supposed to be fully uncredentialed, that is to say, no cookies, no HTTP auth, no TLS client certificates. |
Sorry, I meant that the TLS handshake indicates it's a WebTransport connection and not a "normal" HTTP connection. I see that's covered through SETTINGS_ENABLE_WEBTRANSPORT as @yutakahirano already mentioned above. |
Just to clarify, WebTransport support is an additive property; normal HTTP traffic can occur on WebTransport-supporting connections, though by default a WebTransport object will create a new connection. |
Thanks! That does argue for being conservative with the handshake as servers will be incentivized to flip the WebTransport setting and are not at all incentivized to audit all their "legacy" paths at the same time. |
Given the discussion above, do the followings make sense?
|
I think to be on the safe side you probably want to match WebSocket or "no-cors". Other headers would only come after a CORS preflight normally, after all. |
Ah sorry I overlooked the last comment. |
Meeting:
|
Oh sorry I thought I hit the comment button. My application needs to negotiate a video codec on connect. The client sends a list of supported codecs and the server responds with the chosen one. TLS does something similar. There's how you could implement this:
You could marshal the supported codecs into the request path, but it's a pain. The server still needs to respond with the chosen codec and that's not possible. I would definitely use custom request+response headers if they were available. Only supporting custom request headers would be a marginal improvement. |
What settings is this referring to? If it's the settings set during ALPN I think that is negated (as also stated in prior comments) by the fact that this handshake ends up intermixed with normal HTTP traffic. |
Thank you for your opinion!
I believe it's a new setting - we can define a new setting listing headers which the server accepts for the CONNECT request for webtransport over HTTP/3, for example (let's call it SETTINGS_WEBTRANSPORT_REQUEST_HEADERS for now). Just like SETTINGS_ENABLE_WEBTRANSPORT, if the server supports WebTransport over HTTP/3 and accepts custom headers for the CONNECT request, it should include SETTINGS_WEBTRANSPORT_REQUEST_HEADERS in the initial SETTINGS frame. This is less flexible than CORS preflight but more efficient. |
I see, that would be acceptable (to me, at least). I wonder though, could we generalize that to SETTINGS_BYPASS_CORS_PREFLIGHT or some such so we solve that thorny problem at the same time? See quicwg/base-drafts#1993. Folks (I recall @mnot?) did raise similar concerns in that the person configuring TLS might not be aware of all the HTTP services on the server, but I think we'll always have that problem for any kind of centralized solution. I would hope that documentation would go a long way towards addressing that. (I could also see trying this more limited thing out first and if it works going for the generalized solution later. Dunno how cheap these bits are.) |
Flipping this bit in a SETTING (h2 or h3) has significant performance / race avoidance advantages, so I'm interested. Yes, there are deployments where server administration isn't done by the same people, but I think we can address that risk by:
It might also be interesting to define a companion well-known resource (or Origin Policy property, if that gets off the ground), which would allow control over the SETTING through a resource that's available to the server's content folks (provided that server implementations link the two). I'm happy to write up a draft for the SETTING, but first it'd be great to hear what people like @mikewest think about this. |
cc: @martinthomson |
I'm not seeing any significant new information: yes, this sort of capability might be nice, but it also costs a fair bit to add. It can be added later. |
Meeting:
|
It would be useful to pass a JWT token for authentication / authorization in the connect request. On the server-side, TLS connections are typically terminated by a load balancer, but it would be useful if an JWT token could be passed through to the server instance behind the load balancer. the fetch api has "authentication entries" for this. |
Authentication entries is explicitly not web developer controlled though. |
See the related bug entry about the lack of support for HTTP authentication in the WebSocket API. |
How do we implement authentication with Web Transport? Do we need to store the session token in a non-HTTPOnly cookie or localStorage or something and send it (from the client) as the first message of a session? |
I'd like to link this issue from the WebTransport overview IETF draft: ietf-wg-webtrans/draft-ietf-webtrans-overview#10. At the last IETF meeting (120), the linked issue was brought up (minutes). There was no objection to removing the current prohibition on HTTP Authentication, which was probably due to an earlier version of WebTransport that was less tied to HTTP. To me, (and others judging from WebSocket history at whatwg/websockets#16) it seems preferred to build on top of standard HTTP Authentication schemes rather than relying on less well-defined custom workarounds (like using the URL). While we can defer this, folks are going to need authentication, and the longer we defer the more ad-hoc solutions will pop up. It'll be a worthwhile investment to get this right sooner rather than later. In case it's easier, I think even just supporting authentication related headers for now would be better than nothing. |
The reason for disallowing HTTP authentication is that it ties WebTransport to the HTTP stack, making it harder to implement and opening the floodgates to other HTTP features such as cookies. Experience with the problems this caused for WebSocket implementations was a major driver for this decision. Permitting authentication and other headers to be set from JavaScript seems less problematic, as long as we are confident that servers won't be tricked into bypassing the same-origin policy. |
Without commenting on whether or not HTTP auth is appropriate for WebTransport -- these aren't very convincing reasons. There have been many attempts at creating "protocol neutral" stacks eg SOAP / WS-* -- the reality is that aspects of the underlying layers do sometimes peek through abstractions, necessarily. HTTP Authentication is already widely implemented so supporting it doesn't raise costs significantly. And the ability to choose what features might be useful is hardly "opening the floodgates." |
Even ignoring the question of costs, I think HTTP auth in browsers is generally a terrible feature and we should not bring it to the new APIs. It has dubious privacy properties (is there even an API for logging out?), even worse UX properties (locking up webpage loading with browser-level models for a random subresource), and WebTransport brings its own concerns ( |
We generally don't show dialogs for subresource fetches anymore though. If the user was not previously authenticated for that resource the fetch simply fails. It seems reasonable to prevent it altogether here, though I'm a bit less persuaded that not doing the normal thing for cookies is also good. I suspect that will make it harder for routing middleware to do the right thing. |
Worked with WebSocket protocol quite a lot. The lack of possibility to set custom header in browser results into various hacks:
People always come with questions how to set headers for WebSocket in browsers to reuse existing infrastructures. While in case of Fetch API (including streaming case) all the initial info may be sent in headers or request body – which is effective, obvious and flexible. I've read the discussion, but still do not clearly see why such a functionality can't be added - if it works for Fetch, why it can't be done for WebTransport in browser environment? It seems WebTransport should mainly target browsers and browser specifics even if it can be re-used in different environments? Since it's mostly for browsers, delaying implementation for v2 of WebTransport object can result into a situation we've been many times - some browsers support it, some does not, and all the bunch of workarounds again. My main concern here TBH is not adding the possibility to set custom headers specifically, but possibility to pass some additional custom payload without a need for extra RTT (like we can using Fetch API). Probably it can be done in a different way with WebTransport. Another question I have now after reading the discussion – will WebTransport in the browser include Cookie for requests on the same domain to at least match with current WebSocket behaviour? It would be nice to match in the behaviour here for easier adoption. |
Meeting:
|
It strikes me as a mistake to not include cookies or user-agent supplied HTTP authentication data. I don't see how it changes the security concerns as this is already the default for all HTTP requests. What WebTransport is doing deviates from that and will likely make deployment harder due to inflexible middleware. Also, you cannot allow cross-origin headers to be set without CORS in an HTTP handshake, that especially includes the |
Meeting:
|
Meeting:
|
@annevk - re
What API surface might you have in mind? What restrictions - i.e leveraging forbidden header names. ? |
I don't understand the question. |
My apologies, let me rephrase it more explicitly - you had indicated that it would be a mistake to not include cookies or UA supplied HTTP auth data. Therefore, it should be included in the initial connection. Since we have no means of doing this with the current API surface, we need to extend the API to accomplish this inclusion. One proposal has already been presented.
To that you had previously commented
So if we want to include cookies and auth data in v1, is there a manner of accomplishing it which WebKit would find acceptable? That API + CORS + FETCH FORBIDDEN HEADERS, or a different API, or some other combination of constraints? |
No you don't need to change the API for what I'm saying. You just don't make the fetch with credentials mode set to "omit". Instead you'd use "include", just like WebSockets: https://websockets.spec.whatwg.org/#websocket-opening-handshake. Letting the web developer set credentials would indeed require API surface and would require CORS and such. That's much more involved and is completely separate. |
I think the question of whether WebTransport requests should be credentialed is distinct from the one that's asked in this issue. For what it's worth, unless we make them credentialed, I don't see any circumstances under which a WebTransport request would require a CORS preflight, regardless of whether it has application-specified headers or not. |
It is, it was just that it was brought to my attention here as part of the meeting summary above. I filed #625 on the broader issue as there might well be more than just "credentials mode" I suspect. |
Well, the same-origin policy also guards IP-address-authenticated resources. So please don't do that. |
Don't do what? WebTransport already does not do CORS preflights (neither does WebSocket, for that matter). |
Can we please have this? |
Linked to #264 |
This thread has gotten long. We might need to clarify what "this" is. Are anyone's requirements not met by something like this? (filtered by forbidden header names): const wt = new WebTransport(url, {headers: {foo: 'bar'}});
const response = await wt.ready;
for (const [name, value] of response.headers.entries()) {
...
} |
@annevk do I understand your point to be that a new API for application-provided headers might not be needed if we had cookies and user-agent supplied HTTP authentication data? |
No, that's incorrect. It would lessen the demand (especially for same-site scenarios) and you'd be less inconsistent with the rest of the web platform. |
Web developers may want to attach some information to the request, and encoding everything into the URL is tiresome.
The simplest form is something like this.
This may be dangerous if web developers can specify arbitrary headers. Some examples:
So, we need to forbid forbidden header names at least.
That may not be enough. For usual HTTP requests, if the request is cross-origin and has non-safelisted headers, CORS preflight is needed. WebSocket solves the problem by allowing web developers to control only one header (sec-websocket-protocols). We can do the same for WebTransport.
Thoughts?
The text was updated successfully, but these errors were encountered: