The Double-Edged Sword of HSTS Persistence and Privacy

HTTP Strict Transport Security or more commonly known as HSTS is a draft policy by the IETF WebSec working group currently proposed that would extend the standard list of HTTP response headers to allow domain owners to enroll complying browsers into exclusively secure communications with the web server for an asserted period of time.

This is accomplished by rewriting all HTTP requests to that particular domain regardless of entry (be it via link, image or manually typed in the address bar) over HTTPS and validating the certificate chain. If a secure connection cannot be established or the certificate chain cannot be verified then the request fails with a transport level error and is abandoned.

The actual implementation of this is nearly trivial. Over a secure connection the server simply has to return the header specifying how long the browser should exclusively attempt HTTPS connections and a flag whether it should include sub-domains:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Under normal circumstances as long as the user has been to that domain within the max-age of the policy, this is an effective mitigation against sslstrip type attacks which rely on users to initiate an HTTP connection to perform a man-in-the-middle attack against the browsers.

One of the less understood implications of this proposal is the role that wildcard SSL certificates play. When purchasing an SSL certificate the domain owner must decide between a standard certificate that covers only one particular FQDN such as store.domain.com or a (more expensive) wildcard certificate issued to *.domain.com that would encompass multiple sub-domains such auth.domain.com and store.domain.com.

As the certificate wildcard feature is decoupled from the HSTS includeSubDomains flag it leads to interesting behavior that allows an actor such as an advertising company or any other entity to store, retrieve, and edit data in the browser's database. When a wildcard SSL certificate is used it allows the owner to have a near unlimited number of entires in the HSTS databases as currently implemented by supporting browsers.

An entry in the HSTS database can grant a single-bit of information to an interested party that can be retrieved at a later time. Lets look at an example where we want to store and retrieve the word "HELLO" in a browser's HSTS database using nothing but forum image tags and a trivial encoding.

To set the bits we would simply need to create a post with the following tags:

[img]https://charcount-5.trackingdomain.com/setbit.png[/img]

[img]https://0-H.trackingdomain.com/setbit.png[/img]
[img]https://1-E.trackingdomain.com/setbit.png[/img]
[img]https://2-L.trackingdomain.com/setbit.png[/img]
[img]https://3-L.trackingdomain.com/setbit.png[/img]
[img]https://4-O.trackingdomain.com/setbit.png[/img]

 

When a browser goes to each of these URLs over HTTPS the web server would see the /setbit.png key and include a HSTS header with a large max-age value in the response and create an entry in the browser's HSTS table for each of the sub-domains.

To read this data back out a javascript block on a different domain than the original forum would first brute force the character count by creating resource requests enumerating possible values and having the server respond whether the request came in over HTTP or HTTPS as the requests would have been rewritten by the browser if the sub-domain is present in HSTS database. These requests would look like:

http://charcount-1.trackingdomain.com/getbit.png [ Server: HTTP ]
http://charcount-2.trackingdomain.com/getbit.png [ Server: HTTP ]
http://charcount-3.trackingdomain.com/getbit.png [ Server: HTTP ]
http://charcount-4.trackingdomain.com/getbit.png [ Server: HTTP ]
http://charcount-5.trackingdomain.com/getbit.png [ Server: HTTPS! ]

The same brute-force enumeration process would be performed to retrieve the individual characters of the message body. This enumeration is more effective than the current history enumeration attacks via CSS (here.)

At first this approach looks like a Bloom filter. Seemingly akin to burning in bits permanently and not having the ability to change them but thanks to the max-age specifier of the header it is possible to also clear bits by setting their maximum age to 0:

Request URL: https://charcount-5.trackingdomain.com/clearbit.png
Strict-Transport-Security: max-age=0;

Initially this doesn't look worse than standard tracking cookie as long as it is cleared on a regular basis but clearing the HSTS database frequently renders it much less effective in preventing the very attacks it sought guard against. Therein lies the classic trade-off of security versus privacy. Of the currently two HSTS supporting browsers there is no consensus on this topic. Chrome opts for increased privacy by clearing HSTS database when cookies are cleared while Firefox 4 opts to store HSTS settings in the separate and infrequently cleared site-preferences database.

So what can be done about this?

My proposal is to amend the draft to force the includeSubDomains flag on wildcard certificates. This would limit them to only one entry in the browsers HSTS database and make the technique above prohibitively expensive to non-CA owners as a separate signed SSL certificate would be needed for every bit of information stored and limit encoding options. That way we can have the best of both worlds, privacy and security.