Internet-Draft Optimistic HTTP Upgrade Security August 2023
Schwartz Expires 22 February 2024 [Page]
Workgroup:
HTTPBIS
Internet-Draft:
draft-schwartz-httpbis-optimistic-upgrade-00
Updates:
9298 (if approved)
Published:
Intended Status:
Standards Track
Expires:
Author:
B. M. Schwartz
Meta Platforms, Inc.

Security Considerations for Optimistic Use of HTTP Upgrade

Abstract

The HTTP/1.1 Upgrade mechanism allows the client to request a change to a new protocol. This document discusses the security considerations that apply to data sent by the client before this request is confirmed, and updates RFC 9298 to avoid related security issues.

About This Document

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

Status information for this document may be found at https://datatracker.ietf.org/doc/draft-schwartz-httpbis-optimistic-upgrade/.

Source for this draft and an issue tracker can be found at https://github.com/bemasc/http-upgrade.

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."

This Internet-Draft will expire on 22 February 2024.

Table of Contents

1. 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.

2. Background

In HTTP/1.1, a client is permitted to send an "Upgrade" request header field ([RFC9110], Section 7.8) to indicate that it 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. However, that specification also permits the server to reject the upgrade request:

This rejection of the upgrade is common, and can happen for a variety of reasons:

After rejecting the upgrade, the server will continue to interpret subsequent bytes on that connection in accordance with HTTP/1.1.

[RFC9110] also states:

However, because of the possibility of rejection, the converse is not true: a client cannot necessarily begin using an upgraded protocol merely because it has finished sending the upgrade request message.

In some cases, the client might expect that the upgrade will succeed. If this expectation is correct, the client might be able to reduce delay by immediately sending the first bytes of the upgraded protocol "optimistically", without waiting for the server's response. This document explores the security implications of this "optimistic" behavior.

3. Possible Security Issues

When there are only two distinct parties involved in an HTTP/1.1 connection (i.e., the client and the server), HTTP Upgrade introduces no new security issues: each party must already be prepared 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) with path, headers, or body controlled by a website from a different origin (party 3). Post-upgrade protocols such as WebSocket similarly are often used to convey data chosen by a third party.

If the third-party data source is untrusted, we call the data it provides "attacker-controlled". The combination of attacker-controlled data and optimistic HTTP Upgrade results in two significant security issues.

3.1. Request Smuggling

In a Request Smuggling attack ([RFC9112], Section 11.2) the attacker-controlled data is chosen in such a way that it is interpreted by the server as an additional HTTP request. These attacks allow the attacker to speak on behalf of the client while bypassing the client's own rules about what requests it will issue. Request Smuggling can occur if the client and server have distinct interpretations of the data that flows between them.

If the server accepts an HTTP Upgrade, it interprets the subsequent bytes in accordance with the new protocol. If it rejects the upgrade, it interprets those bytes as HTTP/1.1. However, the client doesn't know which interpretation the server will take until it receives the server's response status code. If it uses the new protocol optimistically, this creates a risk that the server will interpret attacker-controlled data in the upgraded protocol as an additional HTTP request issued by the client.

As a trivial example, consider an upgraded protocol in which the entire post-upgrade content might be freely attacker-controlled (e.g., "connect-tcp" [I-D.ietf-httpbis-connect-tcp]). If the client is authenticated to the server using a connection-level authentication method such as TLS Client Certificates, the attacker could send an HTTP/1.1 POST request in the post-upgrade payload. If the client delivers this payload optimistically, and the upgrade request fails, the server would interpret the payload as a subsequent authenticated request issued by the client.

3.2. Parser Exploits

A related category of attacks use protocol disagreement to exploit vulnerabilities in the server's request parsing logic. These attacks apply when the HTTP client is trusted by the server, but the post-upgrade data source is not. If the server software was developed under the assumption that some or all of the HTTP request data is not attacker-controlled, optimistic use of HTTP Upgrade can cause this assumption to be violated, exposing vulnerabilities in the server's HTTP request parser.

4. Operational Issues

If the server rejects the upgrade, the connection can continue to be used for HTTP/1.1. There is no requirement to close the connection in response to an upgrade rejection, and keeping the connection open has performance advantages if additional HTTP requests to this server are likely. Thus, it is normally inappropriate to close the connection in response to a rejected upgrade.

5. Impact on Existing Upgrade Tokens

At the time of writing, there are four distinct Upgrade Tokens that are registered, associated with published documents, and not marked obsolete. This section considers the impact of this document's considerations on each registered Upgrade Token.

5.1. "HTTP"

[RFC9110] is the source of the requirement quoted in Section 2. It also defines the "HTTP/*.*" family of Upgrade Tokens. In HTTP/1.1, the only potentially applicable versions of this token are "0.9", "1.0", "1.1", and "2.0".

Versions "0.9" and "1.0" are sufficiently syntactically similar to HTTP/1.1 that any such "downward upgrade" would be unlikely to result in the security concerns discussed here. (An "upgrade" to version 1.1 has no effect at all.)

A version number of "2.0" corresponds to HTTP/2. Every HTTP/2 connection begins with a Client Connection Preface (Section 3.4 of [RFC9113]) that was selected to ensure that a compliant HTTP/1.1 server will not process further data on this connection. This avoids security issues if an "HTTP/2.0" Upgrade Token is used optimistically.

5.2. "TLS"

[RFC2817] correctly highlights the possibility of the server rejecting the upgrade. The security considerations documented here are applicable to any use of the "TLS" Upgrade Token, but no change is required in [RFC2817].

5.3. "WebSocket"/"websocket"

Section 4.1 of [RFC6455] 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.

Thus, optimistic use of HTTP Upgrade is already forbidden in the WebSocket protocol. Additionally, the WebSocket protocol requires high-entropy masking of client-to-server frames (Section 5.1 of [RFC6455]).

5.4. "connect-udp"

Section 5 of [RFC9298] says:

  • A client MAY optimistically start sending UDP packets in HTTP Datagrams before receiving the response to its UDP proxying request.

However, in HTTP/1.1, this "proxying request" is an HTTP Upgrade request. This upgrade is likely to be rejected in certain circumstances, such as when the UDP destination address (which is attacker-controlled) is invalid. Additionally, the contents of the "connect-udp" protocol stream can include untrusted material (i.e., the UDP packets, which might come from other applications on the client device). This creates the possibility of Request Smuggling attacks. To avoid these concerns, this text is updated as follows:

  • When using HTTP/2 or later, a client MAY optimistically ...

Section 3.3 of [RFC9298] describes the requirement for a successful proxy setup response, including upgrading to the "connect-udp" protocol, and says:

  • If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the connection.

However, this could be interpreted as an instruction to abort the underlying TLS and TCP connections in the event of an unsuccessful response such as "407 ("Proxy Authentication Required)". To avoid an unnecessary delay in this case, this text is hereby updated as follows:

  • If any of these requirements are not met, the client MUST treat this proxying attempt as failed. If the "Upgrade" response header field is absent, the client MAY reuse the connection for further HTTP/1.1 requests; otherwise it MUST abort the underlying connection.

6. Guidance for Future Upgrade Tokens

There are now several good examples of designs that prevent the security concerns discussed in this document and may be applicable in future specifications:

Future specifications for Upgrade Tokens MUST account for the security issues discussed here and provide clear guidance on how clients can avoid them.

7. IANA Considerations

This document has no IANA actions.

8. References

8.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <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, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/rfc/rfc9110>.
[RFC9298]
Schinazi, D., "Proxying UDP in HTTP", RFC 9298, DOI 10.17487/RFC9298, , <https://www.rfc-editor.org/rfc/rfc9298>.

8.2. Informative References

[I-D.ietf-httpbis-connect-tcp]
Schwartz, B. M., "Template-Driven HTTP CONNECT Proxying for TCP", Work in Progress, Internet-Draft, draft-ietf-httpbis-connect-tcp-00, , <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-connect-tcp-00>.
[RFC2817]
Khare, R. and S. Lawrence, "Upgrading to TLS Within HTTP/1.1", RFC 2817, DOI 10.17487/RFC2817, , <https://www.rfc-editor.org/rfc/rfc2817>.
[RFC6455]
Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6455, DOI 10.17487/RFC6455, , <https://www.rfc-editor.org/rfc/rfc6455>.
[RFC9112]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, , <https://www.rfc-editor.org/rfc/rfc9112>.
[RFC9113]
Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, DOI 10.17487/RFC9113, , <https://www.rfc-editor.org/rfc/rfc9113>.

Acknowledgments

Thanks to Mark Nottingham and Lucas Pardue for early reviews of this document.

Author's Address

Benjamin M. Schwartz
Meta Platforms, Inc.