Re: Working Group Last Call: draft-ietf-httpbis-optimistic-upgrade-03


On May 11, 2025, at 9:48 PM, Martin Thomson <mt@lowentropy.net> wrote:

Section 7 gets this right, but the treatment of Upgrade doesn't.

connect-udp is allowed to be optimistic for reasons that are left unjustified.

I don’t think this is correct.  draft-03 (latest) says

   To avoid these concerns, this text [from CONNECT-UDP] is updated as follows:
         When using HTTP/2 or later, a client MAY optimistically ...

This is meant to ban optimistic sends for CONNECT-UDP in HTTP/1.1.  connect-udp is _not_ allowed to be optimistic.

The original requirement, which was to abort the connection, would seem to be good for HTTP/1.1, with the overreach for HTTPs /2 and /3 being what needs fixing.

We could do this, but it would impose a significant additional performance penalty in order to “mitigate” a vulnerability that does not exist.

The vulnerability in “connect-udp” was mostly hypothetical: it requires registering Capsule Types with values that (as a varint) are also a valid HTTP method name characters and can be issued attacker-controlled at the start of a connection (or to have an extremely “lax” server that tolerates extreme syntax errors in the request).  (No such Capsule Types have been registered (https://www.iana.org/assignments/masque/masque.xhtml#http-capsule-types), nor are they likely to be ever.)

This draft bans optimistic sends in “connect-udp” for HTTP/1.1, closing the hypothetical vulnerability at a 1-RTT performance cost.  (We could have fixed this without the performance cost in various ways, such as with new IANA instructions to prevent dangerous registry entries, but the complexity was deemed too high.)

Requiring servers to close the connection after rejecting an upgrade would add a further performance penalty (when using Proxy Authentication), with extremely limited benefit: it is only helpful if (1) the hypothetical attack is realized _and_ (2) the client does not follow this specification.

The draft _does_ require close-after-rejected-upgrade for CONNECT, because the vulnerability is much less hypothetical.  (It does not require any IANA actions, and some vulnerable clients appear to exist.)  We certainly could impose the same requirement for “Upgrade: connect-udp”, or for all “Upgrade” requests, but that would be primarily for symmetry, rather than to prevent any known attack.  It would also create a significant compatibility risk, for simple clients that rely on the use of a single connection in one way or another.

It seems like the only reason to allow optimistic sending here is latency.  That's important, but we have a solution for that in HTTP/2 and /3, as Section 7 says.  I'd much rather we keep the prohibition for HTTP/1.1.

To be clear, optimistic sending is prohibited.  What is allowed is reuse of a connection after a rejected upgrade.

More generally, there is just one protocol that has chosen the low latency, high risk choice here.  And it's a protocol that is best suited to HTTP/3.  I really don't think that's too hard a position to take.

I don’t think this is accurate.  I believe all the other Upgrade Tokens also permit reuse of the connection after a rejected Upgrade.  WebSocket, for example, is fairly explicit about this (RFC 6455, Section 1.3):

   Any status code other than 101 indicates that the WebSocket handshake
   has not completed and that the semantics of HTTP still apply.

Section 6 has some good advice, but Section 6.1 makes an odd recommendation about using GET with Upgrade to "reduce[] the likelihood that a faulty server implementation might process the request body as the new protocol" (in part, the other part is consistency).  This would seem to miss the point, because it is not the method of the failed request that matters, but the one afterwards.

The fact that GET rarely includes a body is perhaps the only reason that might be relevant here, which might be cause to recommend GET, but the text should say that if it is.  But then it would be making another claim that I think is unwise, which is that you can't convince a client to generate a GET with a body, because that becomes part of the defense.  If it is part of the defense, the draft needs to say that.  I also don't think that it's a reliable defense.

The motivation for this claim was a concern from Glenn Strauss that a sufficiently buggy server implementation might transition to the new protocol too early when processing streaming request bodies (https://github.com/httpwg/http-extensions/issues/2738#issuecomment-1947882765).  Personally, this misbehavior strikes me as rather unlikely.

I’ve proposed text in (https://github.com/httpwg/http-extensions/pull/3089) that would emphasize empty bodies and remove this security claim.

 Again, I'd much rather say that if you try to transition an HTTP/1.1 connection and it fails, stop using the connection.

This section is actually not about any failed upgrade.  Both sides thinks the upgrade has succeeded, but through sheer (hypothetical) bugginess they’ve managed to disagree on where the protocol transition point is.

I realize that this has non-trivial performance costs.  Section 7 explains how to deal with that.

On Mon, May 12, 2025, at 13:10, Tommy Pauly wrote:
Hello HTTP,

This email starts a working group last call for
draft-ietf-httpbis-optimistic-upgrade-03, which has no remaining open
issues currently.

You can find the draft here:
https://urldefense.com/v3/__https://www.ietf.org/archive/id/draft-ietf-httpbis-optimistic-upgrade-03.html__;!!Bt8RZUm9aw!7fSz8MrDjM4X7OOTQyF4Q9ZyHodjQMeEhFrNH0hpZPYs88ZpC2B7SDcVcqc6bVcp3ENYW44aYA$

https://urldefense.com/v3/__https://datatracker.ietf.org/doc/draft-ietf-httpbis-optimistic-upgrade/__;!!Bt8RZUm9aw!7fSz8MrDjM4X7OOTQyF4Q9ZyHodjQMeEhFrNH0hpZPYs88ZpC2B7SDcVcqc6bVcp3EMTMUSynQ$


Please send your review and comments in response to this email, and
file issues to https://github.com/httpwg/http-extensions/issues .

This call will be open until *Monday, May 26*.

Best,
Tommy & Mark

Received on Wednesday, 14 May 2025 15:29:16 UTC