摘要

       本文首先介绍SSL剥离攻击的危害,接着以此为背景引出其防御方法HSTS(HTTP Strict Transport Security),并对其概念、原理、作用及优缺点进行了介绍,继而简述其配置方法,并进行了初步测试。最后是本文的参考文献。

关键词: HSTS,SSL剥离,网络安全


本文地址:https://jjayyyyyyy.github.io/2017/04/27/HSTS.html

1.SSL剥离攻击

1.1 引言

随着互联网的发展,网络安全问题也越来越受到重视,因为一旦信息被盗取或篡改,就有可能给自身带来很严重的损失。SSL剥离就是一种攻击手段,可以窃取、修改传输信息。

1.2 什么是SSL剥离攻击

SSL剥离来自SSL Strip,这个名字初看非常高深,而实际中也会引发很多的安全问题。那么什么是SSL剥离?它有什么危害呢?其实SSL剥离就是将HTTPS连接降级到HTTP连接,从而截获用户的传输内容。

SSL_Strip


1.3 SSL剥离攻击的危害

SSL剥离攻击其实是中间人攻击的一种,顾名思义,就是指攻击者插入到原本直接通信的双方,让双方以为还在直接跟对方通讯,但实际上双方的通信对方已变成了中间人,信息已经是被中间人获取或篡改。

man in the middle attack


举例来说,比如小明和小红上课传纸条,但是纸条每次都要经过小王,然后小王就可以把纸条拆开来看看里面写了啥,也就是信息被中间人获取了。如果小王从中作梗,还可以修改小纸条的内容,这样小红收到以后还以为是小明写的,其实只是中间传输的时候内容被修改了。

而实际发生在网络上的情况是这样的:首先,越来越多的网站为了安全考虑开始使用HTTPS,它使用的是 443 端口进行数据传输,而原来的HTTP的端口是80。但是现在的访问机制存在一个漏洞,也就是允许用户一开始使用HTTP进行请求。

正常情况下,如果用户进行HTTP请求,比如http://www.taobao.com,或者习惯性地直接在地址栏输入taobao.com,这个请求到服务器之后,服务器返回一个302进行重定向,让浏览器用加密的方式去访问https://www.taobao.com,重新发起443端口的请求。从中可以看到,第一次去服务器的连接实际上是不安全的HTTP,第二次去的时候才是安全的HTTPS。

http


这种机制就让攻击者有了可趁之机,进行SSL剥离攻击,也就是在第一次80请求的地方做手脚。攻击者首先劫持用户的80端口,当用户向目标页发起请求时,劫持者模拟正常的HTTPS请求向源服务器获取数据,然后通过80端口返回给用户。也就是下图的过程:

strip


由于HTTP是明文的,上面的这个过程也就相当于:你先把银行卡帐号密码用大家都看得懂的文字给我,然后我去银行拿钱。也就是你与我之间是没有加密的,我与银行之间是加密的,但是因为我有帐号密码,所以我知道如何解密,照样可以拿到钱。当然拿到钱以后,我可以把钱给你,也可以顺便在里面夹杂一些广告,当然也可以拿了钱直接逃之夭夭。

因此如果是与钱相关的帐号密码信息被攻击者拿到了,可不只是小红与小明之间产生误会这么简单了,还可能造成财产损失,因此SSL剥离攻击是相当危险的。

passsword


这种攻击方式非常危险,而且又不能为了安全而要求每个用户每次都在地址栏输入完整的https://,因为这样做会严重影响用户体验。那么对于这种危险,我们该如何防范呢?其实很简单,下面将要介绍的HSTS就可以很方便地防御SSL剥离攻击。


2.HSTS简介

2.1 什么是HSTS

HSTS(HTTP Strict Transport Security) 是一种Web安全协议,它的作用是在本地强制客户端(如浏览器)使用HTTPS与服务器创建连接。服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含STS(Strict-Transport-Security)字段。

secure_your_website_with_hsts


2.2 响应头各个参数的意义

假设在响应头中有如下STS参数:

Strict-Transport-Security: max-age=31536000;
includeSubDomains;
preload;

则各个参数意义如下:

  • max-age 表示这个STS的有效期,单位是秒;
  • includeSubDomains 是可选项,表示将STS规则应用到这个地址的所有子域名;
  • preload 是可选项,表示使用浏览器预载的HSTS地址列表。 其中,HSTS预载列表preload list由Google维护,Chrome/ Firefox/ Safari等浏览器支持预加载的HSTS,避免第一次访问时无法用HSTS建立HTTPS连接的问题,如果某个网站成功提交了加入preload列表的申请,那么它的地址就会出现在这个列表中。
ensure_hsts_is_preloaded


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访问服务器。
lock


因此,如果使用了HSTS,就能防止第一次80请求出问题,它的做法就是不经过网络而是直接在浏览器内部改写地址和请求方式。对应于之前的例子,就相当于你一开始就拥有了一只神奇的笔,用它写下来的文字只有你和银行才能看得懂,我却看不懂。而我拿着这些文字信息到银行后只能换一个保险柜,保险柜的密码只有你和银行知道,因此我也拿不到里面的钱。因此,HSTS有助于安全性的提升。

2.4 浏览器支持

最后,HSTS要起作用首先需要需要浏览器的支持。不过目前主流的浏览器,如Chrome, Safari, Firefox, IE, Opera,其最新版本均已支持HSTS。

browsers



3.能解决什么问题

3.1 三个威胁

HSTS主要针对以下三个威胁:

  • 用户书签中的链接或者手动输入的地址是example.com,然后浏览器以HTTP方式访问。这种方式可能遭遇中间人劫持;
  • HTTPS页面的链接无意中包含HTTP,这个HTTP页面可能被中间人劫持;
  • 在传输过程中可能会被拦截流量,而浏览器显示证书错误链接不安全时用户可能点击继续访问不安全的链接。
12306


3.2 解决方案

HSTS针对以上三个威胁的解决方案:

  • 支持HSTS的浏览器直接内部重定向,用HTTPS取代HTTP访问目标域名;
  • 第二点同上;
  • 在证书错误的时候没有目标页的链接入口,用户不能忽略浏览器警告继续访问网站。
no_unsecure_page_is_allowed


如前所述,若没有使用HSTS,虽然会出现安全警告,但是仍可选择继续不安全的连接。而如果使用了HSTS,则无法继续不安全的链接。

3.3 节省时间和资源

利用HSTS,还可以节省一次302/301跳转请求。如果浏览器已经记住对应网址的HSTS规则,每次对其进行http访问时,都会在浏览器内部直接307跳转到https,不用先80到服务器然后再被告知443端口访问,节省资源和时间。

307


最后,使用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的开发者工具,分别对

  • http://www.taobao.com
  • http://www.baidu.com
  • http://www.douban.com
  • http://www.google.com

进行实验,可以发现taobao, douban, google已经开始使用HSTS,而且在输入上面网址的时候可以看到307状态码,在浏览器内部切换到https进行访问。而访问http://www.baidu.com的时候,还是只有302,多次访问仍旧如此,说明百度首页还没有使用HSTS,仍是先80端口访问然后服务器再返回302告诉浏览器要用443端口进行https访问。

secured_with_hsts



6.参考文献


注:本文最初整理于20160802。接下来将会陆续整理一些以前的学习笔记。

(END)


相关阅读