你以为升级HTTPS就万事大吉了吗???

wens

大部分同学应该都知道 HTTP 协议的网站是不安全的,存在中间人劫持的情况,因此我们平常开发的网页都会将 HTTP 协议升级为 HTTPS,以确保不会被中间人劫持。

注:本文不涉及 HTTPS 的实现原理以及中间人劫持的概念,不了解的同学先去恶补

可是你们以为这样就绝对安全了吗?我们想想下面的场景:

通常情况下,我们打开一个普通的网站可能是通过以下几个方式:

  • 直接点击收藏栏
  • 通过搜索引擎找到
  • 直接输入域名

当采用 直接输入域名 的方式时,如下图所示:
image.png

这时候我们并没有告诉浏览器当前请求的网站协议是https,然而我们最终打开的还是 https 协议的百度网站。这是为什么呢?

其实就是重定向帮我们做了肉眼看不见的事情,具体流程见下图

image.png

那么这个过程中第一步就会涉及名文的传输,因此有了被中间人攻击的机会,所以我们该如何避免这种情况的出现呢?答案就是本文需要介绍的 HSTS

HSTS

MDN 对 HSTS 的定义非常直白

HTTP Strict Transport Security(通常简称为HSTS)是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP

通过定义我们可以画出下面这样的流程图

image.png

当发起 http 的请求,不经过服务器直接变成 HTTPS 将请求发出去。

具体怎么才能让 HSTS 其作用呢?我们接着看。

Strict-Transport-Security

通过给https协议的网站的response header配置Strict-Transport-Security

Strict-Transport-Security: max-age=<expire-time>; includeSubDomains(可选); preload(可选,非标准)

每个属性的定义如下:

  • max-age=<expire-time> -- 在浏览器收到这个请求后的<expire-time>秒的时间内有效。
  • -- 如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
  • preload -- 谷歌维护着一个 HSTS 预加载服务。按照指示成功提交你的域名后,浏览器将会永不使用非安全的方式连接到你的域名。虽然该服务是由谷歌提供的,但所有浏览器都有使用这份列表的意向(或者已经在用了)。但是,这不是 HSTS 标准的一部分,也不该被当作正式的内容。

我们看到百度的网站也设置了Strict-Transport-Security。

image.png

表示在172800秒的时间内访问百度的主页都是以https的形式,不过他并没有设置includeSubDomains这个属性。

细心的同学可能发现了,有一种情况下还是没办法避免中间人劫持。那就是,在用户第一次访问网站并且使用 http 协议的情况下,如果真要全面防止只能通过给域名添加 preload 的方式。具体方法请参加 MDN 添加preload

总结

有了上面的基础,让我们总结一下三种首次访问的情况

  1. 没有HSTS

    1. 浏览器发起http请求
    2. 服务端重定向到https
    3. 浏览器发起https请求
  2. 有HSTS,没有preload

    1. 浏览器发起http请求
    2. 服务端重定向到https
    3. 浏览器发起https请求
    4. 服务器收到https请求,返回数据的同时会添加 strict-transport-security的header,配置参见上文。每次https请求都会刷新这个过期时间。
  3. 有HSTS以及preload(最佳实践)

    1. 浏览器发起http请求
    2. 由于存在preload,浏览器会主动将链接升级为https。

最后我们应该注意,在生产环境下使用 HSTS 应当特别谨慎,因为一旦浏览器接收到HSTS Header(假如有效期是1年),但是网站的证书又恰好出了问题,那么用户将在接下来的1年时间内都无法访问到该网站,直到证书错误被修复,或者用户主动清除浏览器缓存。

阅读 1k
245 声望
4 粉丝
0 条评论
245 声望
4 粉丝
文章目录
宣传栏