Sunday, November 21, 2010

A quick clarification on HSTS (HTTP Strict Transport Security) policy on non-standard ports

Been having an interesting blog comment and twitter discussion with John Wilander.

He wrote a post and some tweets and even filed a Mozilla bug against the HSTS behavior in FF-4.

I posted this to his blog, but thought I'd post it here too.

Essentially there is some confusion about how HSTS works, and how it rewrites ports. The spec is a little vague (or earlier versions were, I think =JeffH fixed it, and if not, I know for a fact he has it on his To-Do list) on what to do about port rewriting.

A few points.

1. HTTP URIs that don't have an explicit port number default to port-80.
2. HTTPS URIs that don't have an explicit port number default to port-443.
3. A URI can specify a non-default port, and the browser will use the port specified.

When we looked at this in determining the proper behavior of the spec, we had a few decisions to make.

HSTS can transparently convert HTTP to HTTPS, and automatically switch from the well-known port-80 to 443 when enforcing TLS.

When the URI has a non-standard port, there are only two "reasonable" behaviors:

1. Don't force TLS, and access the port with HTTP
2. Use the specified port in the URI, but force-TLS on that socket connection

An unreasonable behavior would be:

3. Use some random port calculation scheme and convert the chosen port to another port via some non-standard port number manipulation/rewrite scheme.

We chose #2 as the desired behavior, because #1 leaks cookies which we specifically don't want to do, and #3 is right out because there is no well-known way to calculate the TLS port that corresponds to any other random "high port".

The only way to guarantee that a host is protected on all ports, and a browser refuses to use a cleartext protocol with HTTP, we have to force TLS upgrade on all non-std ports.

I'll go re-read the spec, and if this isn't clear, will make sure we address it in a new draft.

3 comments:

Anonymous said...

Hi, just wondering if you've worked out on #2 solution.

Anonymous said...

I wonder why one cannot simply have the browser remember the port that was used when it first received the HSTS header for a site?

Anonymous said...

This is reallly annoying when you have a setup consisting of the standard posts with HSTS enabled plus a number of internal-only HTTP-only ports (direct to Tomcat, for example) which do not speak https. The browser insists on changing http: to https: and complains of a broken SSL handshake.