The HSTS Cookie (For Firefox 7)

Set Value:
Get Value:

Instructions.

1. Install the StormTide Research CA in your browser. (Save file, Preferences->Advanced->View Certificates->Authorities->Import->Can Identify Websites)
2. Click Set.
3. Click Get.
4. Try to delete your cookies, close your browser, whatever.
5. Come back and click Get. If all went well, a HSTS cookie was remembered.

Notes

Works in Firefox 7.0.1... can be made to work in other browsers

This site is using a research-only certificate authority. If you want to try this out, you'll have to install the CA. (Don't forget to remove it when done) ... In the real world, the HSTS cookie can operate with a normally signed wildcard certificate, but its not worth $200 to me to sign this domain properly.

The HSTS cookie cannot be removed by clearing your cookies. It will be deleted if you clear 'site preferences', however, doing that will also clear a lot of useful information and expire the HSTS pins for other sites.

-- Kevin McArthur

Update: this idea apparently was presented in Chromium bug 33445 by Rsnake.

Source Code


<?php

//Allows XHR requests corss-origin. Could be factored out, don't really need to use XHR at all.
header('Access-Control-Allow-Origin: *');

//Define Server Side Set/Clear Actions. Call Via HTTPS only.
if(!empty($_GET['action']) && $_GET['action'] == 'd') {

    
//Set a Bit
    
if(!empty($_GET['set']) && $_GET['set']=='true') {
        
header('Strict-Transport-Security: max-age=604800;');
    }

    
//Clear a Bit
    
if(!empty($_GET['clear']) && $_GET['clear']=='true') {
        
header('Strict-Transport-Security: max-age=0' );
    }

        
//Make firefox happy that something returned
        
echo "'OK'";
    die();
}

//Define Bit Checking Action. Call by HTTP only.
if(!empty($_GET['action']) && $_GET['action'] == 'g') {
    if(!empty(
$_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
        
//Request was upgraded to HTTPS by HSTS, return a gif. (Credit for hex string to Emptygif.com)
        
header("Content-Type: image/gif");
        echo 
"\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x90\x01\x00\xff\xff\xff\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x01\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x4c\x01\x00\x3b";
    } else {
        
//Request was not upgraded to HTTPS by HSTS, return a 404
        
header('HTTP/1.0 404 Not Found',true404);
    }
    die();
}

?>

<html>
<head>
<script>

//Defines how many bits to store. The more bits the more requests that will be generated.
var maxbits = 8;

function generateNew() {
  valuea=Math.floor(Math.random() * (254) + 1);
  setHSTSCookie(valuea);
}

function getXHR() {
  var req;
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
  } else {
    return null;
  } 
  return req;
}

value=0;

function startrunning() {
  document.getElementById('get').disabled = true;
  document.getElementById('set').disabled = true;
  document.getElementById('clear').disabled = true;
}

function stoprunning() {
  document.getElementById('get').disabled = false;
  document.getElementById('set').disabled = false;
  document.getElementById('clear').disabled = false;
}

function setHSTSCookie(num) {
  clearHSTSCookie();
  startrunning();
  value=0;
  document.getElementById('setvalue').innerHTML = "-setting-";
  document.getElementById('value').innerHTML = "--";
  bits = num.toString(2).length;
  for(i=0; i<bits; i++) {
    xhr = getXHR();
    setorclear=(num.toString(2)[bits-i-1]=="1")?'set=true':'clear=true';
    url = "https://"+ Math.pow(2,i) + ".hstscookie.ca/?action=d&"+setorclear+"&r="+ Math.random();
    xhr.open("GET", url, false);
    xhr.send();
  }
  document.getElementById('setvalue').innerHTML = num;
  stoprunning();
}

function clearHSTSCookie() {
  startrunning();
  document.getElementById('value').innerHTML = "-clearing-";
  document.getElementById('setvalue').innerHTML = "-clearing-";
  for(i=0;i<maxbits;i++) {
    xhr = getXHR();
    url = "https://"+ Math.pow(2,i) + ".hstscookie.ca/?action=d&clear=true&r="+ Math.random();
    xhr.open("GET", url, false);
    xhr.send();
  }
  value=0;
  document.getElementById('setvalue').innerHTML = "--";
  document.getElementById('value').innerHTML = "--";
  stoprunning();
}

function getHSTSCookie() {
  startrunning();
  value=0;
  document.getElementById('value').innerHTML = "-loading-";
  var i;
  for(i=0;i<maxbits;i++) {
    var j = i*1; //closure trick
    img = new Image();
        //load an empty gif for HSTS sites, throw a 404 on http
    img.src = "http://"+ Math.pow(2,i) + ".hstscookie.ca/?action=g&r="+ Math.random();
        img.onload = createOnloadClosure(j);
        img.onerror = createOnerrorClosure(j);
  }
  //set artificial delay to prevent multiple calls. need to add async tracking
  setTimeout("getHSTSCookieMonitor()",3000);
}

function getHSTSCookieMonitor() {
  stoprunning();
}

function createOnloadClosure(bitlevel) {
  return function() { value = value | Math.pow(2,bitlevel); document.getElementById('value').innerHTML = value; }
}

function createOnerrorClosure(bitlevel) {
  return function() { document.getElementById('value').innerHTML = value; }
}

</script>
</head>
<body>
<h1>The HSTS Cookie (For Firefox 7)</h1>
Set Value: <span id="setvalue"></span><br />
Get Value: <span id="value"></span><br /><button id="set" onclick="generateNew()" >Set Cookie</button><button id="get" onclick="getHSTSCookie()">Get Cookie</button><button id="clear" onclick="clearHSTSCookie()">Clear Cookie</button>
<br />
<h2>Instructions.</h2>
1. Install the <a href="/StormTideResearchCA.pem">StormTide Research CA</a> in your browser. (Save file, Preferences->Advanced->View Certificates->Authorities->Import->Can Identify Websites)<br />
2. Click Set. <br />
3. Click Get. <br />
4. Try to delete your cookies, close your browser, whatever. <br />
5. Come back and click Get. If all went well, a HSTS cookie was remembered. <br />
<h2>Notes</h2>
<p>Works in Firefox 7.0.1... can be made to work in other browsers</p>
<p>This site is using a research-only certificate authority. If you want to try this out, you'll have to install the CA. (Don't forget to remove it when done) ... In the real world, the HSTS cookie can operate with a normally signed wildcard certificate, but its not worth $200 to me to sign this domain properly.</p>
<p>The HSTS cookie cannot be removed by clearing your cookies. It will be deleted if you clear 'site preferences', however, doing that will also clear a lot of useful information and expire the HSTS pins for other sites.</p>
<p>-- Kevin McArthur</p>
<p>Update: this idea apparently was presented in <a href="https://code.google.com/p/chromium/issues/detail?id=33445">Chromium bug 33445 by Rsnake</a>.</p> 
<h2>Source Code</h2>
<pre>
<?php show_source(__FILE__); ?>
</pre>
</body>
</html>