Chrome HTTP Transport Security

传统的HTTP连接很容易被中间人攻击。比如当网络流量经过网络运营商的时候,运营商为了私利可能会在HTTP的数据中插入它自己的广告链接,也可能会把HTTP请求重定向到别的网址。随着现代浏览器对HTTPS的支持越来越普遍,很多重要的网站例如www.baidu.com把HTTP协议升级成HTTPS,保证网站的内容在传输的过程中不被篡改。然而大部分普通用户还是习惯在地址栏里输入HTTP网址来访问网站,互联网中也有很多的链接还是HTTP。为了保证兼容性,网站的后台可以把HTTP请求重定向到HTTPS,但是这有两个问题。一是客户端浏览器发起请求还是HTTP,这个过程可能会被中间人攻击,二是网站服务端每次都把HTTP重定向到HTTPS会增大服务器的负担。

HTTP Strict Transport Security

现代的浏览器开始支持一项名为HTTP Strict Transport Security(简称为HSTS)的安全功能,它告诉客户端浏览器只能通过HTTPS访问网站当前资源, 禁止HTTP方式。当网站接收到一个HTTP的请求,然后重定向到HTTPS。这个网站通过HTTPS头Strict-Transport-Security信息通知浏览器,这个网站禁止使用HTTP方式加载,浏览器以后应该自动把所有尝试使用HTTP的请求自动替换为HTTPS请求。我们以百度为例,当我们在Chrome浏览器的地址栏里面输入www.baidu.com,浏览器自动把这个网址扩展成http://www.baidu.com/,然后向服务器发起HTTP请求。

image00

可以看到百度服务器自动把http://www.baidu.com/通过307网络重定向到HTTPS协议https://www.baidu.com/。

image02

然后浏览器客户端再发起HTTPS请求,返回的HTTPS头里面包含下面这一行:Strict-Transport-Security: max-age=172800
这一行的含义是网站服务器告诉浏览器客户端启用HTTP Strict Transport Security功能,之后浏览器访问www.baidu.com应该使用HTTPS协议,过期时间是172800秒。

Chrome中自定义开启域名HSTS

目前支持HSTS功能的网站还不是很多,不过我们可以在Chrome中设置对某个域名开启HSTS。比如我们希望http://labs.jxck.io/strict-transport-security/ 会自动打开https://labs.jxck.io/strict-transport-security/,实际上这个网址是不会自动跳转的。
我们打开chrome://net-internals/#hsts,Add domain里面输入labs.jxck.io。之后我们再打开http://labs.jxck.io/strict-transport-security/ 便会自动跳转到https://labs.jxck.io/strict-transport-security/ 打开。

image03

HSTS Preload List

HSTS还是存在漏洞,第一次通过HTTP访问服务器的时候,服务器还没有返回Strict-Transport-Security响应头,这次会话可能被中间人攻击。因此Chrome维护一个”HSTS Preload List”,里面包含各大公司域名的HSTS信息,在HSTS preload list里面的域名会自动从HTTP切换到HTTPS去访问。你可以去https://hstspreload.appspot.com/ 去查询或者提交域名的HSTS Preload List信息。

HTTP Public Key Pinning

假如浏览器客户端的电脑上被病毒木马植入非法的CA根证书,它就可以任意签发其他域名的证书,HTTPS的安全性就退化成HTTP,其内容可以被病毒木马随意篡改。保证HTTPS链接所使用的数字证书的正确性的安全技术是HTTP Public Key Pinning,简称为HPKP。HPKP响应头指定的白名单证书指纹,只信任客户端证书签发机构(CA)为本域名签发能够匹配上的证书链。以www.facebook.com为例:

image01

public-key-pins-report-only:
max-age=500; pin-sha256=”WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=”; pin-sha256=”r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=”; pin-sha256=”q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ=”; report-uri=”http://reports.fb.com/hpkp/”
它通过pin-sha256指定几个证书指纹,浏览器会与本地的签发该域名的证书链进行对比,如果匹配不上则会通过report-uri上报相关信息。

Chrome自定义HSTS Preload List

Chrome把这份HSTS Preload List硬编码到代码中,https://chromium.googlesource.com/chromium/src/net/+/refs/heads/master/http/transport_security_state_static.json就是原始的数据。但是Chromium并不是直接使用transport_security_state_static.json文件,而是通过transport_security_state_static_generate.go程序读取https://chromium.googlesource.com/chromium/src/net/+/refs/heads/master/http/transport_security_state_static.pins和https://chromium.googlesource.com/chromium/src/net/+/refs/heads/master/http/transport_security_state_static.json里面的数据然后再生成https://chromium.googlesource.com/chromium/src/net/+/refs/heads/master/http/transport_security_state_static.h。
transport_security_state_static_generate.go程序可从https://github.com/chromium/hstspreload 中获取。

TransportSecurity

Chromium里的TransportSecurityPersister类会把通过chrome://net-internals/#hsts添加和访问时收集到HSTS和HPKP信息保存在浏览器的User Data/Default/TransportSecurity文件里面。

参考

https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning

https://developer.mozilla.org/zh-CN/docs/Security/HTTP_Strict_Transport_Security

https://www.chromium.org/hsts

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注