web前端如果想实现cookie跨站点,跨浏览器,清除浏览器cookie该cookie也不会被删除这似乎有点难,下面的教程让你完全摆脱document.cookie
superCookie.js:
http://beta.tfxiq.com/superCookie.js
demo:
服务器端设置HSTS
如PHP:
<?php header("Strict-Transport-Security: max-age=31536000; includeSubDomains
");?>
includeSubDomains必不可少,因为Super Cookie要用到很多子域名(Super Cookie必备条件,最好32个)。
demo用到的子域名:*-hsts-lab.radicalresearch.co.uk 如 1-hsts-lab.radicalresearch.co.uk
,2-hsts-lab.radicalresearch.co.uk
等,demo用到32个子域名 到32-
,为什么用到这么多子域名,下面会谈到。hsts-lab.radicalresearch.co.uk
开
启或关闭HSTS
子域名设置HSTS 状态头:
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/1
在浏览器里打开上面URL,如下图:
上面会有个Strict-Transport-Security的头,max-age=31436000 注意此时max-age不为0,表示HSTS开启了
再打开https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0
此时max-age=0,HSTS失效被关闭了
这个
子域名服务器返回的不同HSTS开启状态是根据url中13-hsts-lab.radicalresearch.co.uk
标红的0/1进行输出不同的状态头的: 0关1开https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0
服务器根据url判断HSTS输出哪种Strict-Transport-Security头
如HSTS开启:<?php header("
Strict-Transport-Security: max-age=31536000; includeSubDomains
");?>
HSTS关闭:
<?php header("
Strict-Transport-Security: max-age=0; includeSubDomains
");?>
这里面还有个关键点是,开启和关闭HSTS必须要用https协议,即在浏览器里打开的时候
下面会有解释。https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0,协议必须是https,这跟HSTS的特性有关。
Super Cookie利用的关键点:
如果我们事先设置了第13个子域名的HSTS的状态开启了,并且在当前浏览器访问过该子域名、或者脚本动态加载过,如浏览器访问过
:
https://13-hsts-lab.radicalresearch.co.uk/hsts/set/1
http://13-hsts-lab.radicalresearch.co.uk/hsts/get
我们会发现http会自动被浏览器重定向到 https://13-hsts-lab.radicalresearch.co.uk/hsts/get
这里特别关键,如果这理解不了,那么HSTS Super Cookie 就无法理解了。
相反如果
HSTS关闭,你再通过http打开该子域名下的任何资源,是不会有任何https跳转的。https://13-hsts-lab.radicalresearch.co.uk/hsts/set/0 你设置
我们再来访问下http://beta.tfxiq.com/sc.html,打开控制台下的network,会发现很多跳转丢失:
这里跳转丢失的原因是因为该子域名下HSTS服务器端开启了,因为你之前用https访问过该域名,并且开启了HSTS,那么后续的所有访问都会被强制跳转到https;
跳转丢失的response也是没有任何返回的,代码就利用到了这一点。
实现原理:
拿http://beta.tfxiq.com/sc.html
为例,当前chrome客户端要保存一个71009647的 cookie值, 71009647的36进制为:169ze7(页面显示值),二进制00000100001110111000010101101111,前面4位黑的0是为了凑全32位。
保存cookie:
按照12进制值00000100001110111000010101101111从左到右的顺序,url最右边的/0或者/1按顺序对应12进制
步骤1: 在
关闭当前子域名HSTShttps://1-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤2: 在
关闭当前子域名HSTShttps://2-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤3: 在
关闭当前子域名HSTShttps://3-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤4: 在
关闭当前子域名HSTShttps://4-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤5: 在
关闭当前子域名HSTShttps://5-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤6: 在
开启当前子域名HSTShttps://6-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤7: 在
关闭当前子域名HSTShttps://7-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤8: 在
关闭当前子域名HSTShttps://8-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤9: 在
关闭当前子域名HSTShttps://9-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤10: 在
关闭当前子域名HSTShttps://10-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤11: 在
开启当前子域名HSTShttps://11-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤12: 在
开启当前子域名HSTShttps://12-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤13: 在
开启当前子域名HSTShttps://13-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤14: 在
关闭当前子域名HSTShttps://14-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤15: 在
开启当前子域名HSTShttps://15-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤16: 在
开启当前子域名HSTShttps://16-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤17: 在
关闭当前子域名HSTShttps://17-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤18: 在
关闭当前子域名HSTShttps://18-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤19: 在
关闭当前子域名HSTShttps://19-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤20: 在
开启当前子域名HSTShttps://20-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤21: 在
关闭当前子域名HSTShttps://21-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤22: 在
开启当前子域名HSTShttps://22-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤23: 在
关闭当前子域名HSTShttps://23-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤24: 在
开启当前子域名HSTShttps://24-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤25: 在
关闭当前子域名HSTShttps://25-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤26: 在
开启当前子域名HSTShttps://26-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤27: 在
开启当前子域名HSTShttps://27-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤28: 在
关闭当前子域名HSTShttps://28-hsts-lab.radicalresearch.co.uk/hsts/set/0
步骤29: 在
开启当前子域名HSTShttps://29-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤30: 在
开启当前子域名HSTShttps://30-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤31: 在
开启当前子域名HSTShttps://31-hsts-lab.radicalresearch.co.uk/hsts/set/1
步骤32: 在
开启当前子域名HSTShttps://32-hsts-lab.radicalresearch.co.uk/hsts/set/1
上面32个步骤,都是根据二进制00000100001110111000010101101111从左到右的顺序,设置了HSTS对应的开启状态,0:关,1:开
保存cookie的 url必须协议是https,原因上面提过,再提一遍,因为开启了HSTS协议,并且通过https加载过该子域名下的任何资源,当再通过http访问任何资源,会发生页面跳转,跳转到https安全协议对应的url.
当然代码在beta.tfxiq.com/superCookie.js中是通过循环动态在head中插入一个script 来模拟浏览器子域名开启和关闭HSTS的
读取cookie:
当用户用相同浏览器再次访问beta.tfxiq.com/sc.html的时候,必须用协议http(注意非常重要,因为要利用HSTS的跳转)去访问1-32的不同子域名,并且传递一个cb的回调函数
步骤1: 在
这个域名HSTS关闭,访问跳转,response没有任何结果,cb回调函数里的参数的值为0,浏览器network中你看到的是取非运算http://1-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘1‘](0)
步骤2: 在
上同http://2-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘2‘](0)
步骤3: 在
上同http://3-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘3‘](0)
步骤4: 在
上同http://4-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘4‘](0)
步骤5: 在
上同http://5-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘5‘](0)
步骤6: 在
这个域名HSTS开启,访问没有跳转,response有数据,cb回调函数里的参数的值为truehttp://6-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘6‘](1)
.
.
等等
.
.
步骤32: 在http://32-hsts-lab.radicalresearch.co.uk/hsts/get?cb=window[‘hsts‘]._[‘32‘](1)
这个域名HSTS开启,访问没有跳转,response有数据,cb回调函数里的参数的值为true
上面32个步骤在superCookie.js中也是通过循环在head中加载script,我们会发现设置Cookie和读取Cookie返回的二进制是一致的,都是00000100001110111000010101101111,00000100001110111000010101101111再转换成71009647,71009647再转换成页面显示的36进制:169ze7
使用32个站点的原因是相当于32位二进制,可以识别20亿个客户端。
缺点:
1、每次读取cookie都需要访问32次子域名,
存取cookie的时候也要加载32次script,开销大、读取cookie速度慢
2、作为一个安全漏洞,以后各大浏览器厂商估计会修复这个bug
优点:
跨站点、浏览器关闭或者清除cookie也删除不了该 HSTS super cookie
上面的解释有点啰嗦,简洁的说是 利用HSTS的漏洞,32个子域名为数据库(
每个子域名代表1或者0,组合起来就是一个unique值),进行数据的存入和读出。
此为原创,如果想转载请注明出处,thanks @author 刘明海