Subject: STARTTLS for HTTP (both versions)

From: Maxthon Chan <[email-masked]>
Date: Thu, 27 Aug 2015 13:34:38 +0800

Hello List.

This idea may have appeared here, but I think it still worth some consideration.

From time to time a website author may want to tell the browser (and user) that their website prefers (or can only be accessed through) HTTPS for connection. Currently this requires server-side rewrite voodoo which requires quite complex configuration on the server. Also there are scenario that a user accidentally access HTTPS site with HTTP requests.

Here I suggest, by using the Upgrade header, to implement some kind of STARTTLS so:

1) the web browser can know and cache the fact that the site prefers HTTPS over HTTP,
2) The accidental HTTP access on HTTPS port can be redirected properly.

The proposed Upgrade syntax is:

Upgrade: STARTSSL[:port]

If the port is omitted, the connection starts TLS handshake immediately after this response in place on the existing connection. If not, even when the port is the same as the current port, current connection is closed and a new connection is made to the port and TLS handshake starts there.

Examples:

The Upgrade header looks like this when visiting http://example.org/ but the site prefers https://example.org/:

Upgrade: STARTTLS:443

For accidental HTTP to HTTPS port, like visiting http://vsphere.example.org:5443/ while the server is HTTPS-only at https://vsphere.example.org:5443/ (I make this kind of mistake a lot when managing VMware vSphere clusters) the browser can get this:

Upgrade: STARTSSL

---

From: Cory Benfield <[email-masked]>
Date: Thu, 27 Aug 2015 09:43:22 +0100

> 2) The accidental HTTP access on HTTPS port can be redirected properly.

This already exists in a different form for HTTP.

The solution to part 1 is the HTTP Strict Transport Security
header[0]. This header instructs a user agent to only access a given
site over HTTPS.

The solution to part 2 is server configuration. Almost all web servers
provide you with configuration that will allow you to respond to all
HTTP requests with a HSTS header and a redirect to the HTTPS
equivalent of the URL. This configuration is rarely particularly
tricky. For example, nginx allows it to be configured very easily:

server {
    listen 80;

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443;

    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

    location / {
        # Whatever config is required
    }
}

It is not clear to me that the Upgrade header proposed provides any
benefit. It is, however, clear to me that this use of the Upgrade
header is unlike the expected uses of the upgrade header, and so would
be a bad idea even if it did provide any benefit.

[0]: http://tools.ietf.org/html/rfc6797

---

From: Maxthon Chan <[email-masked]>
Date: Thu, 27 Aug 2015 17:08:03 +0800

Your proposal does not solve my second scenario, which I will describe in detail here.

Let’s say a software package, for example VMware vSphere, includes a HTTPS-only server, listening on port 5443. Usually to access the said software package you type this into the browser’s address bar: https://vsphere.example.org:5443/. What if you accidentally dropped the ‘s’ in ‘https’? It would be PITA to add the s between http and the colon if the user does not have a mouse, which is very, very common now.

This is why among the two use cases of "Upgrade: STARTTLS” I suggested included not only a jump, but also in-place TLS handshake. The in-place handshake happens in the same TCP connection, immediately following the receiving of a response (with a 4xx status code) that contains this Upgrade: STARTTLS header.

With in-place Upgrade: STARTTLS such scenarios can be avoided.

Also, a Upgrade: STARTTLS of any type implies a Strict-Transport-Security.

> On Aug 27, 2015, at 16:43, Cory Benfield <[email-masked]> wrote:
>

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 27 Aug 2015 12:23:24 +0300

On Thu, Aug 27, 2015 at 05:08:03PM +0800, Maxthon Chan wrote:
> Let’s say a software package, for example VMware vSphere, includes
> a HTTPS-only server, listening on port 5443. Usually to access the
> said software package you type this into the browser’s address bar:
> https://vsphere.example.org:5443/. What if you accidentally dropped
> the ‘s’ in ‘https’? It would be PITA to add the s between http and
> the colon if the user does not have a mouse, which is very, very
> common now.

Sniff the connection type (from the first byte client sends[1]) and
if http://, send redirect to https://?

(And because the stuff is insecure, that redirect does not require
any authentication).

[1] HTTPS connections start with 0x16, HTTP connections start with
printable character.

-Ilari

---

From: Cory Benfield <[email-masked]>
Date: Thu, 27 Aug 2015 10:48:05 +0100

> Also, a Upgrade: STARTTLS of any type implies a Strict-Transport-Security.

The server is clearly not HTTPS-only, because it can speak enough
plaintext HTTP to send the 4XX back with the Upgrade header. Given
that it can do that, it can clearly speak enough plaintext HTTP to
send the 301 with Location header. As far as I can see the only
advantage this extra header has is that it saves a TCP handshake.

---

From: Michael Sweet <[email-masked]>
Date: Thu, 27 Aug 2015 06:15:54 -0400

That's where HTTP Upgrade to TLS (RFC 2817) comes in. Although not widely implemented for the web due to apparent issues with proxies, it has been used for IPP (which uses HTTP/HTTPS) for 15+ years.

Sent from my iPad

> On Aug 27, 2015, at 5:08 AM, Maxthon Chan <[email-masked]> wrote:
>

---

From: Maxthon Chan <[email-masked]>
Date: Thu, 27 Aug 2015 20:18:15 +0800

Under heavy server load and high connection count every saved handshake adds up to the total saved traffic, which in turn amounts to $$$. Also the Upgrade: STARTTLS response itself can be smaller.

The behaviour of Upgrade: STARTTLS on the client side is that the client upgrades to HTTPS and send the same request again. This means that a HTTPS-only server do not need to implement HTTP at all - whenever a connection is not started with a TLS handshake, a static Upgrade: STARTTLS response can be send back immediately, usually before even finish reading the request.

> On Aug 27, 2015, at 17:48, Cory Benfield <[email-masked]> wrote:
>

---

From: Mike Bishop <[email-masked]>
Date: Thu, 27 Aug 2015 16:54:46 +0000

As Michael pointed out, this is RFC 2817.  The static response is status code 426 Upgrade Required, which informs the client that the server will only serve requests over the protocol specified in the Upgrade header.