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

Support sending Exported Authenticators in multiple frames over HTTP/2 #2841

Open
egorbaty opened this issue Jul 23, 2024 · 8 comments
Open

Comments

@egorbaty
Copy link
Contributor

The size of exported authenticators (especially with post quantum certificates) could be large enough that they might not fit in the maximum frame size for HTTP/2, so we'd probably want the ability to send them in multiple frames, similar to CONTINUATION frames.

We cannot actually use CONTINUATION frames per HTTP/2 6.10:

CONTINUATION frames MUST be associated with a stream. If a CONTINUATION frame is received with a Stream Identifier field of 0x00, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR.

One possible solution here that minimizes complexity is to just add a TO_BE_CONTINUED flag for the CERTIFICATE frame type, and make it such that the client must assume CERTIFICATE frames following a received CERTIFICATE frame are continuations of the previously received authenticator fragment. The authenticator would be complete upon receipt of a frame that does not have the flag set.

If that is the form the solution takes, we also might want text that suggests for clients to limit the total size of an authenticator that they would receive to prevent abuse.

@LPardue
Copy link
Contributor

LPardue commented Jul 23, 2024

CONTINUATION was just pwned in the wild. If we are adding a similar design, we'll want to hash out all the security considerations up front

https://nowotarski.info/http2-continuation-flood-technical-details/

@LPardue
Copy link
Contributor

LPardue commented Jul 23, 2024

Would the producer of the EA know the size upfront? If so I'd prefer a design where the sender declares the total size of thing, rather than as a set of chunks.

Furthermore, perhaps consider a setting that declares the maximum size of EA that would be accepted by the recipient.

@egorbaty
Copy link
Contributor Author

Would the producer of the EA know the size upfront? If so I'd prefer a design where the sender declares the total size of thing, rather than as a set of chunks.

Furthermore, perhaps consider a setting that declares the maximum size of EA that would be accepted by the recipient.

I'm not entirely understanding how this differs from the current proposed design. Would we essentially be saying that CERTIFICATE frames would be allowed to have an infinite size and block the control stream?

@LPardue
Copy link
Contributor

LPardue commented Jul 24, 2024

Part of the story with CONTINUATION is that endpoints tend to have limits on the size of header field sections that they allow. But CONTINUATION was able to defeat that in some cases, because its just an unbounded series of frames with no declaration of the total length upfront. Vulnerable implementations were exploited in a number of ways when processing each frames content. Lots of implementations already mitigated it no problem due to said extant limits.

If I'm understanding correctly, we are considering adding a similar model, so we need to think about limits.

@egorbaty
Copy link
Contributor Author

Post IETF-120 update:

A number of different solutions have been proposed here:

  • TO_BE_CONTINUED without any other information. Problematic in similar ways as CONTINUATION is.
  • Extend the use of CONTINUATION frames to the control stream for use with CERTIFICATE frames. Does not address issues with CONTINUATION
  • Waive the maximum frame size for CERTIFICATE frames. Suffers head-of-line blocking over TCP but is very simple to implement and doesn't open up CONTINUATION flood style problems.
  • Create a new stream type for CERTIFICATE frames and define separate rules. Adds a lot of extra complexity to get around HTTP/2 limitations.
  • Send in multiple chunks, but provide a global maximum size, or alternatively specify the total EA size that all of the chunks should add up to.
  • Investigate compression for certificates. Adds a lot of complexity and unknown to be actually possible with EAs.

Waiving the maximum frame size is by far the easiest solution. We might want to determine whether this actually causes any suffering or not (since most EAs today should not be much larger than a single frame anyway)

@LPardue
Copy link
Contributor

LPardue commented Jul 25, 2024

To clarify, does waiving mean ignoring the value of SETTINGS_MAX_FRAME_SIZE when sending or receiving this frame? Such that the maximum length becomes 2^24-1?

If so, maybe it would be good to state that HTTP/3 must also apply this limit to just his frame, to make it easier to pass between proxies that convert between versions.

@egorbaty
Copy link
Contributor Author

To clarify, does waiving mean ignoring the value of SETTINGS_MAX_FRAME_SIZE when sending or receiving this frame? Such that the maximum length becomes 2^24-1?

If so, maybe it would be good to state that HTTP/3 must also apply this limit to just his frame, to make it easier to pass between proxies that convert between versions.

Yup.

And yeah, to the point about applying the limit to H3 as well: Presumably this limit should be plenty so even though the limitation doesn't technically have to exist; imposing it universally could simplify implementations.

I can check on the mailing list but maybe this is the direction we head in for now.

@MikeBishop
Copy link
Contributor

That seems reasonable. It also has the side benefit that the length is indeed stated at the front. The trouble with CONTINUATION is that you have to process the chunks, but all each chunk declares is whether it's the end yet. (Because header compression may be streaming.) In this case, I don't see a scenario where the server would stream these -- it will possess the entire EA in a buffer whose length can be known before beginning to write the frame.

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

No branches or pull requests

3 participants