RFC 9931
Security Considerations for Optimistic Protocol Transitions in HTTP/1.1
RFC 9931: Security Considerations for Optimistic Protocol Transitions in HTTP/1.1 ๐ฆ
- Published by: the Internet Engineering Task Force (IETF) ๐
- Author: B. Schwartz, Meta Platforms, Inc. ๐
- Category: Standards Track ๐
- Date: March 2026 ๐ธ
- Updates: RFC 9112 and RFC 9298 ๐ฅ
- ISSN: 2070-1721 โจ
Abstract โจ
okay so in HTTP/1.1 the client can ask to switch to a new protocol on the same connection ๐. This doc is all about the security stuff that comes up when the client sends data BEFORE the server has said yes, and it adds new requirements to RFC 9112 and RFC 9298 so we don't end up with related security drama ๐ .
Status of This Memo ๐
bestie, this is an Internet Standards Track document ๐.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841.
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc9931.
Copyright Notice ยฉ๏ธ
Copyright (c) 2026 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. Overview
2. Requirements Language
3. Background
4. Possible Security Issues
4.1. Request Smuggling
4.2. Parser Exploits
5. Operational Issues
6. Impact on HTTP Upgrade with Existing Upgrade Tokens
6.1. "TLS"
6.2. "WebSocket"/"websocket"
6.3. "connect-udp"
6.4. "connect-ip"
7. Guidance for Future Upgrade Tokens
7.1. Selection of Request Methods
8. Requirements for HTTP CONNECT
9. Security Considerations
10. IANA Considerations
11. References
11.1. Normative References
11.2. Informative References
Acknowledgments
Author's Address
1. Overview ๐
this doc digs into the security considerations that show up when you switch from HTTP/1.1 to a different protocol on the same connection ๐ฆ. It gives you:
- a review of the relevant standards,
- a discussion of the security risks that may apply if a client sends data before the transition is confirmed,
- a security evaluation of existing upgrade tokens, and
- guidance for implementations and future standards documents.
the updates to [HTTP/1.1] and [CONNECT-UDP], including the new normative requirements, live in Sections 8 and 6.3, respectively ๐.
2. Requirements Language ๐
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document get the BCP 14 treatment ([RFC2119] [RFC8174]). That only happens when they show up in all capitals, exactly like this ๐ . Lowercase is just regular English, bestie ๐.
3. Background ๐
In HTTP/1.1 [HTTP/1.1] and later, a single connection can be used for many requests. In HTTP/2 [HTTP/2] and HTTP/3 [HTTP/3], these requests can be multiplexed, since each request is distinguished explicitly by its stream ID. However, in HTTP/1.1 requests are strictly sequential, and each new request is distinguished implicitly by the closure of the preceding request.
HTTP/1.1 is also the only version of HTTP that lets the client change the protocol used for the rest of the connection ๐ณ. There are two mechanisms to request that kind of protocol transition. The first is the Upgrade header field ([HTTP], Section 7.8). When it's included in a request, it says the client would like to use this connection for a protocol other than HTTP/1.1. The server replies with a 101 (Switching Protocols) status code if it accepts the protocol change ([HTTP], Section 15.2.2).
The other mechanism is the HTTP CONNECT method (Section 9.3.6 of [HTTP]). This method says the client wants to establish a TCP connection to the specified host and port. If it's accepted, the server replies with a 2xx (Successful) response to show that the request was accepted and a TCP connection was established. After that point, the TCP connection is acting as a TCP tunnel, not an HTTP/1.1 connection ๐.
Both of these mechanisms also let the server reject the request. For example, Section 7.8 of [HTTP] says:
A server MAY ignore a received Upgrade header field if it wishes to continue using the current protocol on that connection.
and Section 9.3.6 of [HTTP] says:
A server MUST reject a CONNECT request that targets an empty or invalid port number, typically by responding with a 400 (Bad Request) status code.
Rejected upgrades are super common and can happen for lots of reasons, like:
- The server doesn't support any of the client's indicated upgrade tokens (i.e., the client's proposed new protocols), so it keeps using HTTP/1.1.
- The server knows that upgrading to the offered protocol won't improve anything over HTTP/1.1 for this request to this resource, so it chooses to respond in HTTP/1.1.
- The server requires the client to authenticate before upgrading the protocol, so it replies with the status code 401 (Authentication Required) and provides a challenge in an Authorization response header field ([HTTP], Section 11.6.2).
- The resource has moved, so the server replies with a 3xx (Redirection) status code ([HTTP], Section 3.4).
Servers also reject HTTP CONNECT requests a lot, like when:
- The server doesn't support HTTP CONNECT.
- The specified destination isn't allowed under server policy.
- The destination can't be resolved, is unreachable, or doesn't accept the connection.
- The proxy requires the client to authenticate before proceeding.
After rejecting a request, the server keeps interpreting the bytes it receives on that connection according to HTTP/1.1 ๐.
Section 7.8 of [HTTP] also states:
A client cannot begin using an upgraded protocol on the connection until it has completely sent the request message (i.e., the client can't change the protocol it is sending in the middle of a message).
so in other words, finishing the request message is a necessary condition for the client to start using the new protocol. But it's important to clarify that it is NOT a sufficient condition, because the server might still reject the request ๐ซ.
Sometimes the client can predict that the server is likely to accept a requested protocol transition. For example, if a request using an upgrade token recently succeeded, the client might expect that later requests with the same upgrade token will succeed too. If that expectation is right, the client can often cut down on delay by immediately sending the first bytes of the new protocol "optimistically", without waiting for the server's response โฉ. This document explores the security implications of this "optimistic" behavior ๐.
4. Possible Security Issues ๐จ
When only two distinct parties are involved in an HTTP/1.1 connection (the client and the server), protocol transitions introduce no new security issues. Each party already has to be ready for the other to send arbitrary data on the connection at any time. However, HTTP connections often involve more than two parties if the requests or responses include third-party data ๐ฅ. For example, a browser (party 1) might send an HTTP request to an origin (party 2) where the path, headers, or content are controlled by a website from a different origin (party 3). Post-transition protocols, such as WebSocket [WEBSOCKET], are also frequently used to carry data chosen by a third party ๐งฉ.
If the third-party data source is untrusted, then the data it provides is potentially "attacker-controlled" ๐. Attacker-controlled data combined with optimistic protocol transitions leads to two significant security issues ๐.
4.1. Request Smuggling ๐ฅท
In a Request Smuggling attack ([HTTP/1.1], Section 11.2), the attacker-controlled data is crafted so the server interprets it as an additional HTTP request. These attacks let the attacker speak on behalf of the client while getting around the client's own rules about which requests it will issue. Request Smuggling can happen if the client and server have different interpretations of the data flowing between them ๐.
If the server accepts a protocol transition request, it interprets the following bytes according to the new protocol. If it rejects the request, it interprets those bytes as HTTP/1.1. But the client can't know which interpretation the server will take until it gets the server's response status code ๐ฌ. If the client uses the new protocol optimistically, there's a risk that the server will read attacker-controlled data in the new protocol as an additional HTTP request issued by the client ๐ฉ.
As a simple example, picture an HTTP CONNECT client providing connectivity to an untrusted application. If the client is authenticated to the proxy server using a connection-level authentication method, such as TLS Client Certificates ([TLS], Section 4.4.2), the attacker could send an HTTP/1.1 POST request ([HTTP], Section 9.3.3) to the proxy server at the start of its TCP connection ๐ต๏ธ. If the client delivers this data optimistically and the CONNECT request fails, the server would misread the application's data as a later authenticated request issued by the client ๐.
## REQUESTS ##
# The malicious application requests a TCP connection to a nonexistent
# destination, which will fail.
CONNECT no-such-destination.example:443 HTTP/1.1
Host: no-such-destination.example:443
# Before connection fails, the malicious application sends data on the
# proxied TCP connection that forms a valid POST request to the proxy.
# The vulnerable client optimistically forwards this data to the proxy.
POST /upload HTTP/1.1
Host: proxy.example
Content-Length: 123456
<POST body controlled by the malicious application>
## RESPONSES ##
# When TCP connection establishment fails, the proxy responds by
# rejecting the CONNECT request, but the client has already forwarded
# the malicious TCP payload data to the proxy.
HTTP/1.1 504 Gateway Timeout
Content-Length: 0
# The proxy interprets the smuggled POST request as coming from the
# client. If connection-based authentication is in use (e.g., using
# TLS client certificate authentication), the proxy treats this
# malicious request as authenticated.
HTTP/1.1 200 OK
Content-Length: 0
Figure 1: Example Request Smuggling Attack Using HTTP CONNECT ๐โจ
4.2. Parser Exploits โจ
okay so this one is a whole category of sneaky attacks ๐ต๏ธโโ๏ธ they work by exploiting a disagreement about the protocol to break the server's request parser ๐ the catch is the HTTP client is trusted by the server, but the data coming in after the transition is NOT trusted ๐ if the server software was built on the assumption that some or all of the HTTP request data is not attacker-controlled, then optimistic sending can break that assumption and expose holes in the server's HTTP request parser ๐ฅ not me finding out parsers are this fragile ๐ญ
5. Operational Issues ๐ธ
if the server rejects the transition request, the connection can keep being used for HTTP/1.1 ๐ฆ there is no general requirement to close the connection in response to a rejected transition, and keeping it open has performance perks if more HTTP requests to that server are likely to show up ๐ so it's normally inappropriate to close the connection in response to a rejected transition ๐
6. Impact on HTTP Upgrade with Existing Upgrade Tokens ๐
this section is about how all of this affects some registered upgrade tokens [IANA-UPGR] that are believed to be in use at the time of writing ๐ the tea is spilled in the subsections below ๐ต
6.1. "TLS" ๐
the "TLS" family of upgrade tokens was defined in [RFC2817], which correctly calls out that the server might reject the upgrade โ if a client ignores that possibility and sends TLS data optimistically, the result can't be valid HTTP/1.1 ๐ the first octet of a TLS connection must be 22 (ContentType.handshake), but that's not an allowed character in an HTTP/1.1 method (see [TLS], Section 5.1 and [HTTP/1.1], Section 3) ๐ฅฒ a compliant HTTP/1.1 server will treat this as a parsing error and close the connection without processing further requests ๐ซ
6.2. "WebSocket"/"websocket" ๐ง
Section 4.1 of [WEBSOCKET] says:
Once the client's opening handshake has been sent, the client MUST wait for a response from the server before sending any further data.
so optimistic use of HTTP Upgrade is already forbidden in the WebSocket protocol ๐ โโ๏ธ on top of that, the WebSocket protocol requires high-entropy masking of client-to-server frames (Section 5.1 of [WEBSOCKET]) ๐ง we love a protocol that's already thought this through ๐
6.3. "connect-udp" ๐ฆ
Section 5 of [CONNECT-UDP] says:
A client MAY optimistically start sending UDP packets in HTTP Datagrams before receiving the response to its UDP proxying request.
BUT ๐ in HTTP/1.1, this "proxying request" is an HTTP Upgrade request ๐ that upgrade is likely to get rejected in certain situations, like when the UDP destination address (which is attacker-controlled) is invalid โ also, the contents of the "connect-udp" protocol stream can include untrusted material (aka the UDP packets, which might come from other applications on the client device) ๐ฌ that opens the door to Request Smuggling attacks ๐จ to dodge all of this, this document replaces that text so HTTP/1.1 is excluded from any optimistic sending, like so:
A client MAY optimistically start sending UDP packets in HTTP Datagrams before receiving the response to its UDP proxying request but only if the HTTP version in use is HTTP/2 or later. Clients MUST NOT send UDP packets optimistically in HTTP/1.x due to the risk of Request Smuggling attacks.
6.4. "connect-ip" ๐
the "connect-ip" upgrade token is defined in [CONNECT-IP] โจ Section 11 of [CONNECT-IP] forbids clients from sending packets optimistically in HTTP/1.1, so this issue gets avoided ๐
7. Guidance for Future Upgrade Tokens ๐ฎ
there are now several good examples of designs that reduce or eliminate the security concerns in this document, and they may be useful in future specs ๐ก
- Forbid optimistic use of HTTP Upgrade (Section 4.1 of [WEBSOCKET] and Section 11 of [CONNECT-IP]).
- Embed a fixed preamble that deliberately terminates HTTP/1.1 processing (Section 3.4 of [HTTP/2]).
- Apply high-entropy masking of client-to-server data (Section 5.1 of [WEBSOCKET]).
future specs for upgrade tokens should account for the security issues discussed here and give clear guidance on how implementations can avoid them ๐ซถ
7.1. Selection of Request Methods ๐
some upgrade tokens, like "TLS", are defined for use with any ordinary HTTP method ๐ the upgraded protocol keeps providing HTTP semantics and will convey the response to that HTTP request โจ
the other upgrade tokens mentioned in Section 6 don't preserve HTTP semantics, so the method isn't relevant for them ๐คทโโ๏ธ all of these upgrade tokens are specified only for GET requests with no content ๐ง
future specifications for upgrade tokens should restrict their use to GET requests with no content if the HTTP method is otherwise irrelevant and the request doesn't need to carry any message content ๐ this improves consistency with other upgrade tokens and simplifies server implementation ๐
8. Requirements for HTTP CONNECT ๐ฉท
this document updates [HTTP/1.1] to include the remaining text of this section ๐ the requirements here apply only to HTTP/1.1 ๐
proxy clients that send CONNECT requests on behalf of untrusted TCP clients MUST do one or both of the following:
- Wait for a 2xx (Successful) response before forwarding any TCP payload data.
- Send a "Connection: close" request header.
proxy clients that don't implement at least one of these two behaviors are vulnerable to a trivial Request Smuggling attack ([HTTP/1.1], Section 11.2) ๐ฑ
at the time of writing, some proxy clients are believed to be vulnerable as described ๐ซฃ as a mitigation, proxy servers MUST close the underlying connection when rejecting a CONNECT request, without processing any further requests on that connection ๐ช this requirement applies whether or not the request includes a "close" connection option ๐
note that this mitigation will frequently cause slower connection establishment for correctly implemented clients, especially when returning a 407 (Proxy Authentication Required) response ๐ข this performance loss can be avoided by using HTTP/2 or HTTP/3, which are not vulnerable to this attack ๐
as a performance optimization, proxy servers MAY disable this mitigation if the client is known to wait for a 2xx (Successful) response before forwarding untrusted TCP payload data (i.e., complying with item 1 above) ๐ง proxy servers can identify compliant clients using the request's User-Agent header field and the user agent vendor's documentation regarding its compliance ๐
9. Security Considerations ๐จ
this document describes security considerations related to optimistic use of protocol transitions in HTTP/1.1 ๐ read the whole thing before you ship anything that sends data early, bestie ๐ญ
10. IANA Considerations ๐ท
this document has no IANA actions โจ
11. References ๐
11.1. Normative References
[CONNECT-UDP]Schinazi, D., "Proxying UDP in HTTP", RFC 9298, DOI 10.17487/RFC9298, August 2022,<https://www.rfc-editor.org/info/rfc9298>.[HTTP]Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022,<https://www.rfc-editor.org/info/rfc9110>.[HTTP/1.1]Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022,<https://www.rfc-editor.org/info/rfc9112>.[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/info/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/info/rfc8174>.
11.2. Informative References
[CONNECT-IP]Pauly, T., Ed., Schinazi, D., Chernyakhovsky, A., Kรผhlewind, M., and M. Westerlund, "Proxying IP in HTTP", RFC 9484, DOI 10.17487/RFC9484, October 2023,<https://www.rfc-editor.org/info/rfc9484>.[HTTP/2]Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, DOI 10.17487/RFC9113, June 2022,<https://www.rfc-editor.org/info/rfc9113>.[HTTP/3]Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, June 2022,<https://www.rfc-editor.org/info/rfc9114>.[IANA-UPGR]IANA, "Hypertext Transfer Protocol (HTTP) Upgrade Token Registry",<https://www.iana.org/assignments/http-upgrade-tokens/>.[RFC2817]Khare, R. and S. Lawrence, "Upgrading to TLS Within HTTP/1.1", RFC 2817, DOI 10.17487/RFC2817, May 2000,<https://www.rfc-editor.org/info/rfc2817>.[TLS]Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,<https://www.rfc-editor.org/info/rfc8446>.[WEBSOCKET]Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6455, DOI 10.17487/RFC6455, December 2011,<https://www.rfc-editor.org/info/rfc6455>.
Acknowledgments ๐ซถ
this document benefited from valuable reviews and suggestions by:
- Mike Bishop
- Mohamed Boucadair
- Gorry Fairhurst
- Mark Nottingham
- Kazuho Oku
- Lucas Pardue
- David Schinazi
- Glenn Strauss
- Michael Sweet
- Willy Tarreau
- Martin Thomson
Author's Address ๐
Benjamin M. Schwartz Meta Platforms, Inc. Email: ietf@bemasc.net
the end, bestie ๐โจ that's the whole RFC 9931 glow-up ๐
๐ฆ where this page comes from
- ietf: rfc9931 2026-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms