本文整理自HSTS学习笔记、 HSTS详解、什么是中间人攻击?如何避免?这三篇的文章
1.中间人攻击
“中间人攻击(MiTM)”就是当数据离开一个端点前往另一个端点时,传输的期间便是对数据失去控制的时候。当一个攻击者将自己置于两个端点并试图截获或阻碍数据传输时,便称为中间人(MiTM)攻击。
攻击手段
谈及MiTM时,并不是只有一种方式可以造成损害——答案是四种!一般说来,有嗅探、数据包注入、会话劫持和SSL剥离。
-
嗅探:嗅探或数据包嗅探是一种用于捕获流进和流出系统/网络的数据包的技术。网络中的数据包嗅探就好像电话中的监听。记住,如果使用正确,数据包嗅探是合法的;许多公司出于“安全目的”都会使用它。
-
数据包注入:在这种技术中,攻击者会将恶意数据包注入常规数据中。这样用户便不会注意到文件/恶意软件,因为它们是合法通讯流的一部分。在中间人攻击和拒绝式攻击中,这些文件是很常见的。
-
会话劫持:你曾经遇到过“会话超时”错误吗?如果你进行过网上支付或填写过一个表格,你应该知道它们。在你登录进你的银行账户和退出登录这一段期间便称为一个会话。这些会话通常都是黑客的攻击目标,因为它们包含潜在的重要信息。在大多数案例中,黑客会潜伏在会话中,并最终控制它。这些攻击的执行方式有多种。
-
SSL剥离:SSL剥离或SSL降级攻击是MiTM攻击的一种十分罕见的方式,但是也是最危险的一种。众所周知,SSL/TLS证书通过加密保护着我们的通讯安全。在SSL剥离攻击中,攻击者使SSL/TLS连接剥落,随之协议便从安全的HTTPS变成了不安全的HTTP,从而截获用户的传输内容。
2.HSTS
2.1什么是HSTS
HSTS(HTTP Strict Transport Security) 是一种Web安全协议,它的作用是在本地强制客户端(如浏览器)使用HTTPS与服务器创建连接。服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含STS(Strict-Transport-Security)字段。
2.2响应头各个参数的意义
语法规则
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
复制代码
各个参数的意义
- max-age:它是必选参数,是一个以秒为单位的数值,它代表着HSTS Header的过期时间,通常设置为1年,即31536000秒。
- includeSubDomains是可选参数,如果包含它,则意味着当前域名及其子域名均开启HSTS保护
- preload是可选参数,表示使用浏览器预载的HSTS地址列表,其中,HSTS预载列表preload list由Google维护,Chrome/ Firefox/ Safari等浏览器支持预加载的HSTS,避免第一次访问时无法用HSTS建立HTTPS连接的问题,如果某个网站成功提交了加入preload列表的申请,那么它的地址就会出现在这个列表中,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它
2.3原理与作用过程
2.3.1网址不在preload列表中的情况
- 在服务器端设置响应头,添加
Strict-Transport-Security
,并设置max-age等参数; - 用户第一次访问时,服务器把含有STS的响应头发给客户端(浏览器);
- 下次浏览器如果使用HTTP访问该网址,只要max-age未过期,浏览器内部会进行307跳转,直接HTTPS访问服务器。
2.3.2 网址存在preload列表中的情况
- 在服务器端设置响应头,添加
Strict-Transport-Security
,并设置max-age等参数; - 浏览器如果使用HTTP访问该网址,只要max-age未过期,浏览器内部会进行307跳转,直接HTTPS访问服务器。
因此,如果使用了HSTS,就能防止第一次80请求出问题,它的做法就是不经过网络而是直接在浏览器内部改写地址和请求方式。对应于之前的例子,就相当于你一开始就拥有了一只神奇的笔,用它写下来的文字只有你和银行才能看得懂,我却看不懂。而我拿着这些文字信息到银行后只能换一个保险柜,保险柜的密码只有你和银行知道,因此我也拿不到里面的钱。因此,HSTS有助于安全性的提升。
3.能解决的问题
3.1三个威胁
HSTS主要针对以下三个威胁:
- 用户书签中的链接或者手动输入的地址是example.com,然后浏览器以HTTP方式访问。这种方式可能遭遇中间人劫持;
- HTTPS页面的链接无意中包含HTTP,这个HTTP页面可能被中间人劫持;
- 在传输过程中可能会被拦截流量,而浏览器显示证书错误链接不安全时用户可能点击继续访问不安全的链接。
3.2 解决方案
HSTS针对以上三个威胁的解决方案:
- 支持HSTS的浏览器直接内部重定向,用HTTPS取代HTTP访问目标域名;
- 第二点同上;
- 在证书错误的时候没有目标页的链接入口,用户不能忽略浏览器警告继续访问网站。
如前所述,若没有使用HSTS,虽然会出现安全警告,但是仍可选择继续不安全的连接。而如果使用了HSTS,则无法继续不安全的链接。
3.3 节省时间和资源
利用HSTS,还可以节省一次302/301跳转请求。如果浏览器已经记住对应网址的HSTS规则,每次对其进行http访问时,都会在浏览器内部直接307跳转到https,不用先80到服务器然后再被告知443端口访问,节省资源和时间。
最后,使用HSTS的优点是可以强制客户端使用HTTPS访问页面,避免中间人劫持;免去一次302/301的跳转请求,直接进行HTTPS连接,节省时间和资源。更加安全和高效。但是它也存在一些缺点:
- 无法处理纯IP的请求,也即如果在地址栏输入http://2.2.2.2,即便响应头中设置了STS,浏览器也不会处理。(参考资料中未设置,但是用百度的IP不会建立HTTPS连接,而如果用淘宝网首页的IP会显示501错误);
- 因为HSTS只能在80和443端口之间切换,如果服务是8080端口,即便设置了STS,也无效;
- 如果浏览器证书错误,一般情况会提醒存在安全风险,然是依然给一个链接进入目标页,而 HSTS 则没有目标页入口,所以一旦证书配置错误,会导致根本无法访问,用户体验很差;
- 如果服务器的HTTPS没有配置好就开启了STS的响应头,并且还设置了很长的过期时间,那么在你服务器HTTPS配置好之前,用户都是没办法连接到你的服务器的,除非max-age过期了。
4.配置服务器
4.1 Apache2
修改配置文件,如/etc/apache2/sites-enabled/websites.conf和/etc/apache2/httpd.conf
,在VirtualHost中增加以下内容:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
</VirtualHost>
复制代码
4.2 Lighttpd
修改配置文件,如/etc/lighttpd/lighttpd.conf
,然后重启Lighttpd即可:
server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
setenv.add-response-header = ("Strict-Transport-Security" => "max-age=63072000; includeSubdomains; ")
}
复制代码
4.3 Nginx
将以下内容添加到https的配置文件中即可:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; ";
复制代码
5.初步测试
利用Chrome的开发者工具,分别对
进行实验,可以发现taobao, douban, google已经开始使用HSTS,而且在输入上面网址的时候可以看到307状态码,在浏览器内部切换到https进行访问。而访问http://www.baidu.com的时候,还是只有302,多次访问仍旧如此,说明百度首页还没有使用HSTS,仍是先80端口访问然后服务器再返回302告诉浏览器要用443端口进行https访问。