Ne v kontakte Antisocial programmer's place

HSTS Super Cookie

Demonstration

Your cookie is set to:

Your cookie is:

What is this?
This is an abuse of HTTP Strict Transport Security technology, which is used to tag people and track them in similar manner as storing a cookie in a browser.
Why "super"?
First, it's much harder to get rid of compared to regular cookie: most of modern browsers provide user with no interface to manage HSTS storage. Second, in some browsers (mostly in Chromium-based) HSTS cookie will remain even when site is accessed in "private mode". Third, Safari iOS and OS X, when connected to iCloud, share and sync HSTS storage across devices, so being marked on one machine user becomes trackable on all his devices. See below for details.
Time to panic?
Nope. This technique isn't practical as it requires a whole bunch of additional requests to be performed to identify a visitor. Again, see below for details.

What is this?

HSTS technology allows HTTPS-supporting server to tell browser to send queries to a specific domain over HTTPS only, even if URL explicitly specified HTTP (without "S") schema. This was designed to reduce possibility of man-in-the-middle attacks which strip all HTTPS links down to plain HTTP, making them vulnerable to eavesdropping.

To prevent that, server sends Strict-Transport-Security: "max-age=<number_of_seconds>" header, which tells browser that it must send all queries to that host for next number_of_seconds over HTTPS only.

It was noticed that this means that browser stores one bit of information per domain (or subdomain) and to could be read with specially crafted script. Original demonstration of this (along with detailed explanation of HSTS) was created by Radical Research and utilized JavaScript to write and read bits from browser's HSTS storage.

I've been wondering if it's possible to track even paranoid NoScript visitors and after several attempts came up with such implementations. You can see it in action on upper-right corner of this page.

How does this work?

Assume that we have an evil website (say, hsts.nevkontakte.com) which has 8 subdomains like 1.hsts.nevkontakte.com, 2.hsts.nevkontakte.com, ..., 8.hsts.nevkontakte.com and additional subdomain tag.nevkontakte.com. Having this, we're able to store 9 bits of information in visitor's browser.

When a user visits http://hsts.nevkontakte.com/ for the first time

  1. Browser fetches stylesheet http://tag.hsts.nevkontakte.com/dispatch.css.
  2. This request will arrive to server over plain HTTP telling server that this is user's first visit of hsts.nevkontakte.com and server will reply with redirect to https://tag.hsts.nevkontakte.com/setup.css.
  3. Once server receives request for setup.css, it does several things:
    1. Sends HSTS header for tag.hsts.nevkontakte.com, so next request to dispatch.css will be sent over HTTPS.
    2. Generates 8-bit identifier for the visitor and for each bit generates URL of format , where N is a bit number from 1 to 8 and X is 1 or 0 depending on value of corresponding bit in the identifier.
    3. Replies with CSS, which imports all eight stylesheets mentioned above, making browser to fetch them all.
  4. For all requests to https://N.hsts.nekvkontakte.com/set/1.css server replies with header Strict-Transport-Security: "max-age=31536000", forcing all further requests to that subdomain to be sent over HTTPS.
  5. For all requests to https://N.hsts.nekvkontakte.com/set/0.css server replies with header Strict-Transport-Security: "max-age=0", allowing further requests to that subdomain to be sent over plain HTTP.

On the next visit to http://hsts.nevkontakte.com/

  1. Browser forces request to http://tag.hsts.nevkontakte.com/dispatch.css to be carried over HTTPS, telling server that this is returning visitor.
  2. Server generates random token and associates 8-bit variable with it, initially set to 0.
  3. For each if 8 bits server generates URL http://N.hsts.nekvkontakte.com/get/<token>.css and responds with CSS, which includes all this sub-stylesheets.
  4. Browser starts fetching sub-stylesheets and if on a first visit corresponding bit was 1, browser will force such request over HTTPS, following HSTS policy.
  5. Upon receiving request for http://N.hsts.nekvkontakte.com/get/<token>.css, server will set N-th bit of variable associated with token to 1 or 0, depending over which protocol request has arrived.
  6. Once all 8 requests have been received, server will have complete identifier of the visitor. Viola!
You can find complete PoC sources at GitHub.

Time to panic!

This PoC demonstrates how powerful CSS can be combined with a bit of server-side magic, although it isn't usually regarded as a possible source of threat. Compared to original demo by Radical Research presented technique is even more scary due to following:

  • It works with NoScript enabled.
  • Any domain can simply add http://tag.hsts.nevkontakte.com/dispatch.css stylesheet to enable tracking.
  • CSS-based approach might overcome cross-domain policy to a certain extent, being able to provide feedback using element:after {content: "some information"}.

Scratch that! No panic.

Despite of said above, HSTS super cookie doesn't provide any practical threat to user's privacy. First and the most important is that it required one additional request per bit of identifier. This drastically slows down page load and no site which cares about it's audience can afford this. For example, this page uses 31 bit identifier. Assuming that browser opens up to 8 parallel connections per page and ping time to the server 100ms, it would take at least ~1.5 sec to fetch tracking-related stylesheets (dns + tcp handshake + request-response).

Second, although Chromium makes available HSTS records from regular mode to private browsing, it doesn't keep HSTS records received in private mode. So if you visit tracking site in private mode only, HSTS cookie will be destroyed as soon as you end private session. Firefox doesn't make make HSTS regular storage in private mode at all (which I personally consider wrong) and current version of IE doesn't support HSTS at all. So, there isn't much to be afraid of, really.