Upgrading to TLS Within HTTP/1.1
updated by
- rfc-7230 — Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
- rfc-7231 — Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
updates
- rfc-2616 — Hypertext Transfer Protocol -- HTTP/1.1
Extracted elements (21)
The 426 status code is a 4xx (client error) rather than a 3xx (redirect) because 3xx redirection would fail for user agents that do not understand Upgrade. A UA treating 426 as 300 would look for a Location header and retry without TLS, failing again. A distinct 4xx code provides an unambiguous failure signal that prevents silent downgrade loops.
The hop-by-hop definition of Upgrade was a deliberate design choice to allow incremental deployment on either side of proxies and to permit optimized protocols between cascaded proxies without requiring all parties to participate in or be aware of the protocol change.
The HTTP/1.1 Upgrade mechanism allows TLS to be initiated over an existing TCP connection, enabling secure and unsecured HTTP to share port 80. This avoids the practice of allocating parallel 'secure' port numbers (e.g., 443), which effectively halves the number of available well-known ports. The IESG reaffirmed in 1997 that issuing parallel secure port numbers should be deprecated.
Using a cleartext HTTP/1.1 Upgrade preamble before the TLS handshake solves the 'virtual hosting' problem for TLS. Because TLS's initial handshake does not specify the intended hostname (relying on IP address), sending a cleartext Host: header before upgrading allows a server to select the correct certificate for name-based virtual hosting.
A proxy that does not recognize 426 Upgrade Required may strip the accompanying Upgrade header before forwarding, preventing the client from learning the required protocol upgrade. If a client receives 426 without an Upgrade header, it must request an end-to-end CONNECT tunnel and repeat the request.
The HTTP/1.1 Upgrade header is a hop-by-hop mechanism negotiated between each adjacent pair of HTTP counterparties, not end-to-end. A proxy receiving an Upgrade header and responding with 101 changes the protocol only on its own connection segment, not the full path. This means TLS upgrade via Upgrade: alone cannot provide end-to-end security across proxies.
A proxy MUST NOT respond with any 2xx status code to a CONNECT request unless it has either a direct or tunnel connection established to the target authority. If the proxy can only reach the origin through another proxy, it SHOULD issue a CONNECT to that next proxy.
If an unsecured response would be unacceptable, a client MUST send an OPTIONS request first (rather than the actual request) to initiate the switch to TLS/1.0. This avoids sending sensitive request data before TLS is established.
If the server is prepared to initiate the TLS handshake, it MUST send an intermediate '101 Switching Protocols' response and MUST include an Upgrade response header specifying the ordered bottom-up protocol stack it is switching to (e.g., 'Upgrade: TLS/1.0, HTTP/1.1').
In the HTTP Upgrade Token Registry, the responsible party for the first registration of a 'product' token MUST approve later registrations of a 'version' token combined with that product token before the version token can be registered.
Once the TLS handshake completes successfully, the server MUST continue with the response to the original request. Any TLS handshake failure MUST lead to disconnection per the TLS error alert specification.
When offering an optional upgrade, a client MAY include 'Upgrade: TLS/1.0' and 'Connection: Upgrade' headers in any clear HTTP request. The server MAY respond normally to the clear request OR switch to secured operation by sending a 101 response.
The '426 Upgrade Required' HTTP status code is defined. A server uses it to indicate that a client request cannot be completed without TLS; the response MUST include an Upgrade header specifying the required TLS version token. The server SHOULD include a human-readable message body explaining the reason.
The CONNECT method requests that a proxy establish a TCP tunnel on the client's behalf. The Request-URI MUST be an 'authority' (host:port), not a full URL. For example: 'CONNECT server.example.com:443 HTTP/1.1'. Proxy authentication (e.g., Proxy-Authorization) may be used with CONNECT.
The 'TLS/1.0' Upgrade token is defined as the identifier for the TLS protocol in the HTTP Upgrade header field. A client includes 'Upgrade: TLS/1.0' and 'Connection: Upgrade' in a request to signal its desire to switch to TLS.
This document establishes the HTTP Status Code Registry, defining the namespace for Status-Code tokens in HTTP responses. Initial values come from HTTP/1.1 (RFC 2616), WebDAV (RFC 2518, codes 420-424), WebDAV Advanced Collections (code 425), and this document (code 426). New values SHOULD be standards-track documents within the IETF Applications Area.
This document establishes the HTTP Upgrade Token Registry, defining the namespace for product tokens used in the Upgrade HTTP header field. Registrations are on a First Come First Served basis; each token must name a responsible party and point of contact. Once registered, a token stays registered forever. This document registers 'TLS/1.0'.
A man-in-the-middle attacker can delete the Upgrade header from a client request, preventing TLS negotiation and leaving the connection in cleartext — analogous to rewriting https:// links to http://. This risk exists only when a server is willing to serve content over both secure and insecure channels. Clients that know a server is TLS-compliant can mitigate this by only using OPTIONS requests (mandatory upgrade path) rather than optional upgrade.
The CONNECT method creates a generic TCP tunnel and carries significant security risks. Proxy operators SHOULD restrict CONNECT tunneling to a small set of known ports. A client could abuse CONNECT to reach arbitrary ports (e.g., port 25 to relay SMTP spam), since tunneled data is opaque to the proxy.
Widespread use of 'http:' URIs for both secure and insecure resources (enabled by this mechanism) means the URI scheme alone no longer signals security properties. The choice of required security characteristics is delegated to client and server policy, such as user preferences or server-side resource access rules.
The TLS-over-HTTP upgrade state machine: (1) Client sends HTTP request with 'Upgrade: TLS/1.0'; (2) Server responds 101 Switching Protocols; (3) Both parties immediately begin TLS handshake after the blank line ending the 101 response; (4) On TLS success, server completes the original HTTP request; on TLS failure, connection is terminated.