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.
<?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',true, 404);
}
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>