Skip to main content

Using HTTP/3 Stream Limits in HTTP/2
draft-thomson-httpbis-h2-stream-limits-00

Document Type Active Internet-Draft (individual)
Authors Martin Thomson , Lucas Pardue
Last updated 2023-11-06
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-thomson-httpbis-h2-stream-limits-00
HTTP                                                          M. Thomson
Internet-Draft                                                   Mozilla
Intended status: Standards Track                               L. Pardue
Expires: 9 May 2024                                           Cloudflare
                                                         6 November 2023

                  Using HTTP/3 Stream Limits in HTTP/2
               draft-thomson-httpbis-h2-stream-limits-00

Abstract

   A variant mechanism for managing stream limits is described for
   HTTP/2.  This scheme is based on that used in QUIC and is more robust
   against certain patterns of abuse.

About This Document

   This note is to be removed before publishing as an RFC.

   The latest revision of this draft can be found at
   https://martinthomson.github.io/h2-stream-limits/draft-thomson-
   httpbis-h2-stream-limits.html.  Status information for this document
   may be found at https://datatracker.ietf.org/doc/draft-thomson-
   httpbis-h2-stream-limits/.

   Discussion of this document takes place on the HTTP Working Group
   mailing list (mailto:ietf-http-wg@w3.org), which is archived at
   https://lists.w3.org/Archives/Public/ietf-http-wg/.

   Source for this draft and an issue tracker can be found at
   https://github.com/martinthomson/h2-stream-limits.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

Thomson & Pardue           Expires 9 May 2024                   [Page 1]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

   This Internet-Draft will expire on 9 May 2024.

Copyright Notice

   Copyright (c) 2023 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Revised BSD License text as
   described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
   2.  Conventions and Definitions . . . . . . . . . . . . . . . . .   3
   3.  The HTTP/2 MAX_STREAMS Frame  . . . . . . . . . . . . . . . .   4
     3.1.  Applying Stream Limits  . . . . . . . . . . . . . . . . .   5
     3.2.  Negotiating MAX_STREAMS Usage . . . . . . . . . . . . . .   5
   4.  Security Considerations . . . . . . . . . . . . . . . . . . .   6
   5.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .   6
   6.  References  . . . . . . . . . . . . . . . . . . . . . . . . .   6
     6.1.  Normative References  . . . . . . . . . . . . . . . . . .   6
     6.2.  Informative References  . . . . . . . . . . . . . . . . .   7
   Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .   7
   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .   7

1.  Introduction

   HTTP/2 allows endpoints to declare the concurrency limit for streams
   created by their peer (SETTINGS_MAX_CONCURRENT_STREAMS; see
   Section 5.1.2 of [HTTP/2]).  Initially, the stream concurrency limit
   is only bounded by the maximum number of streams that can be created,
   which is 2^30 for each endpoint, but the value can be changed at any
   time.  Most endpoints set a smaller value in an attempt to protect
   the resources that are committed when processing a stream.

   This limit is not effective in the case that streams are quickly
   cancelled.  The creator of a stream can cancel it using the
   RST_STREAM frame.  The creator of a stream could also cause its peer
   to send RST_STREAM by purposefully sending frames that violate HTTP/2
   rules, unless errors also cause the peer to close the connection.
   Either of these methods has deterministic and immediate effect, which
   means that the stream no longer counts against the concurrent stream

Thomson & Pardue           Expires 9 May 2024                   [Page 2]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

   limit.  This means that a malicious endpoint can create or cancel an
   unbounded number of streams as long as its peer does not set a limit
   of zero.  For clarity, we'll refer to either of these methods as
   "cancelling".

   If the creation of the stream results in the expenditure of
   resources, rapidly creating and cancelling streams can exhaust
   resources.  For a server, clients that create and cancel many
   requests can effectively deny service; for a client, reserving and
   cancelling promised streams might have similar effect if a client
   does not disable server push using the SETTINGS_ENABLE_PUSH setting.
   This creates a denial of service exposure for which a remedy is not
   supported in the protocol.

   However, as noted in Section 10.5 of [HTTP/2], many of the features
   in HTTP/2 that have some potential to create denial of service
   attacks also have constructive uses.  Distinguishing constructive and
   destructive uses is often challenging.  Some applications of HTTP
   might find that cancelling many requests is necessary; if
   cancellation is treated as abusive, it is possible that the treatment
   necessary to prevent attacks might unintentionally punish some
   clients.

   The QUIC protocol [QUIC] on which HTTP/3 [HTTP/3] is built contains
   an alternative mechanism for limiting concurrency.  The scheme in
   QUIC, as described in Section 4.6 of [QUIC], does not set a
   concurrent stream limit, but instead relies on a peer increasing the
   maximum allowed stream identifier.  An endpoint cannot create new
   streams immediately after cancelling an open stream; their peer needs
   to send a message to make more streams available.  In QUIC therefore,
   a malicious endpoint can only create and cancel a finite number of
   streams, after which their peer needs to provide consent to continue.

   This document ports the QUIC stream concurrency limit mechanisms to
   HTTP/2.  As use of this system is voluntary and therefore not
   necessarily guaranteed, this does not prevent abusive use of stream
   cancellation.  However, deployment of this mechanism in popular
   implementations might allow endpoints to deploy more aggressive
   strategies for managing abuse in its absence.

2.  Conventions and Definitions

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

Thomson & Pardue           Expires 9 May 2024                   [Page 3]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

3.  The HTTP/2 MAX_STREAMS Frame

   The MAX_STREAMS frame (type=0xTBD) is used to limit the streams that
   a recipient is permitted to create.

   The format of the MAX_STREAMS frame is illustrated in Figure 1, using
   the notation defined in Section 1.3 of [QUIC].

   MAX_STREAMS Frame {
     Length (24) = 0x04,
     Type (8) = 0x0TBD,

     Unused Flags (8),

     Reserved (1),
     Stream Identifier (31) = 0,

     Reserved (1),
     Maximum Stream Identifier (31),
   }

                     Figure 1: MAX_STREAMS Frame Format

   In addition to the common HTTP/2 frame header (see Section 4 of
   [HTTP/2]), the MAX_STREAMS contains a one-bit reserved field and a
   31-bit Maxmimum Stream Identifier field.

   The Reserved field MUST be set to zero when sending and ignored on
   receipt.

   The Maximum Stream Identifier field contains the maximum value of
   stream identifier that a recipient of this frame can use when it
   creates or reserves a stream; see Section 5.1 of [HTTP/2] for how
   streams are created.

   A MAX_STREAMS frame MUST be sent on stream 0.  Receipt of a
   MAX_STREAMS frame on any other stream MUST be treated as a connection
   error of type PROTOCOL_ERROR; see Section 5.4.1 of [HTTP/2].

   An endpoint MUST treat receipt of a MAX_STREAMS frame with a length
   other than 4 as a connection error of type FRAME_SIZE_ERROR; see
   Section 5.4.1 of [HTTP/2].

Thomson & Pardue           Expires 9 May 2024                   [Page 4]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

   A client MUST treat receipt of an even-numbered Maximum Stream
   Identifier as a connection error of type PROTOCOL_ERROR; see
   Section 5.4.1 of [HTTP/2], with an exception of a value of 0, which
   can be used to indicate support for the feature without enabling the
   creation of streams (see Section 3.2).  Similarly, a server MUST
   treat receipt of an odd-numbered Maximum Stream Identifier as a
   connection error.

3.1.  Applying Stream Limits

   An endpoint that receives a MAX_STREAMS frame MUST NOT create or
   reserve a stream with a number that exceeds the value of the Maximum
   Stream Identifier field from that frame, until it receives a
   MAX_STREAMS frame with a larger value.

   An endpoint MUST treat the creation or reservation of a stream with a
   higher valued stream identifier than it included in a MAX_STREAMS
   frame as a connection error of type FLOW_CONTROL_ERROR; see
   Section 5.4.1 of [HTTP/2].

   Endpoints can only increase the value that they include in a
   MAX_STREAMS frame.  An endpoint MUST treat receipt of a Maximum
   Stream Identifier that is equal to or smaller than a value that it
   has previously received as a connection error of type PROTOCOL_ERROR;
   see Section 5.4.1 of [HTTP/2].  Note that a value of 0 can be sent
   one time by either client or server to indicate support for this
   feature without permitting the creation of streams; see Section 3.2.

   An implementation can support a similar concurrency limit to that
   provided by SETTINGS_MAX_CONCURRENT_STREAMS.  The initial value can
   be set to twice the value of SETTINGS_MAX_CONCURRENT_STREAMS, with a
   client adding 1 if the value is non-zero.  The endpoint then
   increases the value of the Maximum Stream Identifier field as the
   streams its peer initiates are closed.  An endpoint can avoid sending
   redundant MAX_STREAMS frames by processing all incoming data before
   increasing the maximum.  This approach differs from
   SETTINGS_MAX_CONCURRENT_STREAMS in that a peer is not able to create
   and cancel streams arbitrarily, as new streams do not become
   available until after receiving a MAX_STREAMS frame.

3.2.  Negotiating MAX_STREAMS Usage

   This extension is not negotiated using the SETTINGS frame.  Instead,
   the receipt of a MAX_STREAMS frame indicates support for the feature.

   An endpoint that supports this extension MUST send a MAX_STREAMS
   frame after establishing a connection, after the HTTP/2 connection
   preface (Section 3.4 of [HTTP/2]).  When a MAX_STREAMS frame is

Thomson & Pardue           Expires 9 May 2024                   [Page 5]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

   received, the endpoint MUST subsequently only create streams
   according to the rules in Section 3.1 and ignore any value of the
   SETTINGS_MAX_CONCURRENT_STREAMS setting.

4.  Security Considerations

   HTTP/2 considered the cancellation of a stream to reclaim the
   resources that might have been committed during its creation.  The
   stream limits in HTTP/2 therefore did not provide a means to limit
   stream creation.  Though cancellation is a potential source of
   abusive traffic, it was not explicitly mentioned (see Section 10.5 of
   [HTTP/2]).  However, experience has shown that the creation of a
   stream has costs that cannot always be recovered when that stream is
   cancelled.

   The use of the MAX_STREAMS frame provides endpoints with a means of
   limiting stream creation, using a method that has proven to be
   effective in QUIC.  However, repeated use of the MAX_STREAMS frame is
   also a potential source of abuse, as described in Section 10.5 of
   [HTTP/2].  Though processing a MAX_STREAMS frame is likely to be
   trivial, receiving significantly more MAX_STREAMS frames than the
   number of streams that have been closed might indicate an attempt to
   waste effort.

5.  IANA Considerations

   This document registers a new entry in the "HTTP/2 Frame Type"
   registry, as documented in Section 11 of [HTTP/2].  This entry has
   the following values.

   Frame Type:  MAX_STREAMS

   Code:  0xTBD

   Specification:  Section 3

6.  References

6.1.  Normative References

   [HTTP/2]   Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113,
              DOI 10.17487/RFC9113, June 2022,
              <https://www.rfc-editor.org/rfc/rfc9113>.

   [QUIC]     Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based
              Multiplexed and Secure Transport", RFC 9000,
              DOI 10.17487/RFC9000, May 2021,
              <https://www.rfc-editor.org/rfc/rfc9000>.

Thomson & Pardue           Expires 9 May 2024                   [Page 6]
Internet-Draft    Using HTTP/3 Stream Limits in HTTP/2     November 2023

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.

6.2.  Informative References

   [CVE-2023-44487]
              "HTTP/2 Rapid Reset CVE Record", 10 October 2023,
              <https://www.cve.org/CVERecord?id=CVE-2023-44487>.

   [HTTP/3]   Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114,
              June 2022, <https://www.rfc-editor.org/rfc/rfc9114>.

Acknowledgments

   This document is written in response to the problems discovered as
   part of [CVE-2023-44487], so maybe those behind the botnet
   responsible for that attack deserve some credit.

Authors' Addresses

   Martin Thomson
   Mozilla
   Email: mt@lowentropy.net

   Lucas Pardue
   Cloudflare
   Email: lucaspardue.24.7@gmail.com

Thomson & Pardue           Expires 9 May 2024                   [Page 7]