HTTP严格传输安全协议 (HSTS)

HSTS

HTTP协议最初通过TCP传输,后为了传输安全,加入了SSL/TLS作为中间层,称为HTTPS(HTTP over SSL)。当在浏览器中输入一个域名访问时,浏览器默认会通过HTTP协议访问服务器,服务端可以返回301以跳转到HTTPS,此后所有数据传输通过HTTPS传输。然而,中间人攻击者可能会攻击拦截初始的http请求,从而控制用户后续的回话。

HTTP Strict Transport Security,即HSTS协议提供了一个机制,让服务端可以主动告知浏览器,以后的请求全部严格地通过HTTPS进行。

HSTS如何工作

启用HSTS

服务端向浏览器发送响应时,可以在响应头部中添加Strict-Transport-Security,告知浏览器开启HSTS。

如响应头部中有Strict-Transport-Security: max-age=86400表示为当前域名启用HSTS,过期时间为1天。

如响应头部中有Strict-Transport-Security: max-age=259200; includeSubDomains表示为当前域名和所有的子域名启用HSTS,过期时间为30天。

Tips

  • 只有在安全传输中Strict-Transport-Security头部才会生效。在HTTP(而不是HTTPS)中Strict-Transport-Security头部会被忽略
  • max-age的值为TTL(即生存时间),值为0时(例如Strict-Transport-Security: max-age=0)浏览器将关闭此域名的HSTS设置

浏览器自动跳转HTTPS

对于开启了HSTS的域名,浏览器将强制采用HTTPS。

1. 直接访问域名时跳转

在浏览器中访问域名时,如果域名开启了HSTS,浏览器将发生内部跳转,直接跳转到HTTPS进行访问。即使用户手动输入http://domainname访问,仍会发生强制跳转。

2. 网页中的链接跳转

网页中的资源,如果其URL的域名启用了HSTS,浏览器请求此资源时将自动跳转的HTTPS。 如网页中有链接<img src="http://qlee.in/static/logo.img>,而且qlee.in开启了HSTS,浏览器将自动到https://qlee.in/static/logo.img请求相应的资源。

3. 端口的处理

HTTP默认采用80端口,HTTPS默认采用443端口。当浏览器因为HSTS执行内部跳转时

  • 1 如果没有显式指定端口,浏览器跳转时也不会显式指定端口,默认HTTPS会访问443端口
  • 2 如果指定了80端口,浏览器跳转时会将端口转换为443端口
  • 3 如果指定了其他端口,浏览器跳转时会保留指定的端口

HSTS对SSL连接的影响

HSTS中的Strict不只是强制跳转到HTTPS,也包含了对HTTPS连接建立的处理。开启HSTS后,一旦有警告或者错误,浏览器将直接关闭HTTPS连接。包括以下几种

  1. SSL证书过期或者验证失败。没有开启HSTS时,一旦遇到证书过期、域名不匹配、签名验证失败等情况,浏览器将要求用户选择是否继续。而开启HSTS后,浏览器将关闭连接,无法继续访问。
  2. 证书通过OCSP或CRLs等方式被撤销。

取消HSTS

1. 服务器端关闭HSTS

服务端可以通过响应的添加头部Strict-Transport-Security: max-age=0或者Strict-Transport-Security: max-age=0; includeSubDomains来告知浏览器关闭域名的HSTS

2. 浏览器端关闭HSTS

对于chrome浏览器,地址栏中输入chrome://net-internals/#hsts进入HSTS设置页面,可以查询、删除指定域名的HSTS设置,也可以手动为域名开启HSTS。

对于chrome和firefox浏览器,可以通过删除域名的历史记录来清除域名的HSTS设置。

HSTS preload list

google维护了一个称为“HSTS preload list”的站点域名和子域名列表,主流的web浏览器(Chrome, Firefox, Opera, Safari, IE 11 and Edge) 都采用了该域名列表,对列表中的域名强制开启HSTS。域名的所有者可以通过https://hstspreload.org/提交其域名。

参考链接