使用HSTS嗅探浏览器历史纪录的三个缝隙
HSTS是让浏览器强制运用HTTPS拜访网站的一项安全战略。HSTS的规划初衷是缓解中间人进犯带来的危险。本文首要介绍HSTS及其他Web功用带来的一些隐私问题,比方怎么运用它们来勘探浏览器的用户历史纪录。
一、布景:什么是HSTS
HSTS的英文全称是HTTP Strict Transport Security,中文译作HTTP严厉传输安全。2012年11月IETF发布RFC 6797,在这篇文档中正式界说了HSTS。HSTS的敞开办法是在HTTP呼应头中参加Strict-Transport-Security字段。如:Strict-Transport-Security: max-age=31536000 。这意味着在接下来的31536000秒内(1年),当浏览器需求拜访同一个域名时,有必要运用HTTPS,而且用户不能够疏忽证书过错正告。运用HSTS防止了一系列的中间人进犯问题,比方HTTPS剥离进犯 [1]、HTTPS Cookie注入进犯 [2]等。
设置HTTP呼应头的办法尽管能够躲避很多的中间人进犯,可是用户的第一次拜访仍然是不受HSTS维护的。所以诞生了浏览器预置HSTS列表。网站站长能够主意向Chrome团队提交自己的域名。同意后,各干流浏览器厂商(不只是Chrome)会在编译新版浏览器时将你的域名硬编码进内置HSTS列表中。
现在已经有越来越多的网站敞开了HSTS,比方Google、百度、支付宝等。依据trustworthyinternet.org 发布的SSL Pulse陈述显现,到2019年5月,有11.8%的网站支撑HSTS [3]。最新版的干流浏览器也都支撑HSTS,比方Chrome、Edge、IE 11、Firefox、Opera、Safari等。
二、缝隙一:运用端口号和标签勘探历史纪录
上一节所述的都是HSTS好的一方面,下面来说HSTS导致的问题。第一个缝隙是我和Vlad Tsyrklevich在2014年独立发现的 [4][5]。简略来说,假如www.example.com敞开了HSTS,假如用户没有拜访过它,那么http://www.example.com:443/favicon.ico必定会拜访失利。假如拜访过,那么HSTS会使浏览器恳求https://www.example.com:443/favicon.ico,这样就会成功(假如不存在favicon.ico这个图片的话,就任选一个这个域名下其他图片地址)。所以咱们用http://www.example.com:443/favicon.ico" onerror="not_visited()" >,假如onerror被调用就阐明没有拜访过www.example.com,假如onload被调用就阐明拜访过。
这个办法有必定的约束,比方被测验的域名有必要要运用HSTS,而且不能在HSTS预置列表中。而且只能判别一个域名是否拜访过,而无法测验整个URL是否被拜访过。
这个缝隙我报给了Chromium团队,陈述和完好PoC可拜见 [4]。我的主张是制止http协议运用443端口。可是由于这样会给WebSocket形成兼容性问题,而且这个缝隙影响小,所以他们终究决议不修正这个缝隙。
网站能够把自己的域名提交到HSTS预置列表来躲避这个缝隙。用户能够经过清空历史纪录防止这个缝隙,由于清空历史记载会一起清空动态设定的HSTS记载。
三、缝隙二:Sniffly — 运用HSTS和CSP勘探历史纪录
这个缝隙是由yahoo的安全工程师Yan Zhu于2019年发现的。她在Toorcon 2019会议上叙述了这个缝隙(讲演视频拜见[6],幻灯片拜见[7]),并把这个缝隙命名为Sniffly。Freebuf之前也有一篇文章《Sniffly: 运用HSTS和CSP嗅探浏览器历史记载》[8],便是写这个缝隙的。
这个缝隙运用CSP(内容安全战略)来阻挠https协议的图片,而一起答应http协议。这个CSP是这样设置的:Content-Security-Policy: img-src http://*。这样假如有一个http到https的重定向,那么这个CSP将在这个重定向发作之后,阻挠https恳求,并调用onerror handler。进犯者能够运用JavaScript来测从http恳求发出到https被阻挠之间的时刻距离,这个时刻距离便是重定向所需时刻。假如这个时刻很短(小于10毫秒),那么咱们能够以为浏览器没有向服务器发送任何恳求,也便是说这个重定向来源于HSTS或者是缓存的301重定向。这样咱们就知道用户从前拜访过这个域名。
这个缝隙很快地在Chrome中修正了,缝隙编号是CVE-2019-1617。修正办法是:假如CSP中指定了http://*,则它一起答应http和https协议。这样就没法用这个办法屏蔽http到https的重定向。Yan Zhu给Chrome提交的缝隙陈述和PoC可拜见 [9]。
四、缝隙三:运用HSTS、CSP和端口号勘探历史记载
这个缝隙是我在2019年,看完缝隙二的细节后想出来的绕过办法。首要咱们看Google对缝隙二的修正代码 [10]:
补丁在WebKit/Source/core/frame/csp/CSPSource.cpp文件中的CSPSource::schemeMatches函数中参加了下面4行代码:
if (equalIgnoringCase(m_scheme, "http"))
return equalIgnoringCase(url.protocol(), "http") || equalIgnoringCase(url.protocol(), "https");
if (equalIgnoringCase(m_scheme, "ws"))
return equalIgnoringCase(url.protocol(), "ws") || equalIgnoringCase(url.protocol(), "wss");
这个代码的意思便是当CSP中的协议是http时,url的协议是http或https都能成功匹配。ws是WebSocket协议,相同CSP中指定的ws协议能够一起匹配ws和wss。
很显然这个修正只考虑了URL中的协议部分,所以我想到运用缝隙一中的技巧,咱们在CSP中显式指定端口号,就绕过了修正。
比方,咱们设置这个CSP战略:img-src http://example.com:80。缝隙二修正之后,这个CSP会答应http://example.com:80和https://example.com:80,可是后一个URL并没有意义,由于https不必80端口,而真实的https://example.com仍然被阻挠,由于https的端口号不匹配”:80”。有了这个思路之后,剩余的运用办法就和缝隙二一样了,也是测http到https的重定向时刻。
这个缝隙一起存在于Chrome、Firefox、WebKit。但Edge、IE不存在这个缝隙。Edge是在https恳求回来之后才调用onerror,所以Edge中无法核算重定向时刻。
给Chrome的陈述和PoC在[11],给Mozilla的陈述在[12],给WebKit的陈述在[13]。他们都早已修正结束。缝隙编号是CVE-2019-5137(Chrome)和CVE-2019-9017(Firefox)。Google还给了我1000美元奖金。
五、总结
这篇文章首要介绍了什么是HSTS以及和HSTS相关的三个缝隙。这三个缝隙影响都不大,可是我写出来首要为了共享,怎么灵活运用端口号这个技巧来绕过相关约束。HSTS其实还能当Cookie用,也是HSTS带来的隐私问题,鉴于和本文关系不大,就不触及了