likes
comments
collection
share

你不能不知道的安全性 HTTP headers

作者站长头像
站长
· 阅读数 29
作者:Larry Lu译者:前端小智来源:stackabuse

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

随着网络上的 Web 应用越来越多,为了提升安全性,现在跟安全性有关的 HTTP header 也是多到记不得。因为各种不同功能的 HTTP header 实在太多,所以这边想要介绍几个比较简单、好设定的安全性 headers ,只要把这些 headers 加进去,网站就会突然变安全哦~

Content Security Policy (CSP)

首先是历史悠久的 CSP,这个 header 是用来限制浏览器只能从哪些地方载入资源。譬如说我设定 Content-Security-Policy: default-src larry.com,就代表我限制浏览器只能从 larry.com 这个域名载入图片、CSS、字体等等各种资源

当然想设定很多个域名也是可以的,只要一直往下接就可以了。下图开发者工具的内容是我上 Github 首页时 response header 裡的 CSP 设定,他就是把 uploads.github.comapi.github.com 等等很多个网域都加进去,虽然看起来很冗长,但至少有一个白名单,不会莫名其妙载入其他域名的东西

你不能不知道的安全性 HTTP headers

如果想针对不同类型的资源有不同的 policy(虽然比较麻烦但会更安全),那也可以写成 Content-Security-Policy: img-src a.com; font-src b.com 的形式,那浏览器就会知道你希望只能从 a.com 载入图片、从 b.com 载入字体

想看还有哪些属性可以设定可以参考 MDN 上的 Directives

那限制域名有什么用呢?假如哪天黑客在我的网站上发现了一个 XSS 漏洞,让他可以在首页的 HTML 中加入一段 <script src=“hacker.com/evil.js”>,那每一个使用者到我的网站时浏览器就会载入恶意的 evil.js,让黑客可以做一些坏坏的事情,譬如说重新导向、偷走帐号密码等等

但如果有把 CSP 设定成 Content-Security-Policy: default-src larry.com 的话,浏览器就会拒绝载入 evil.js(下图),因为那个脚本是从 hacker.com 来的。因此虽然 CSP 不能完全防堵 XSS,但能减轻 XSS 造成的影响,因为如果攻击者不能从外部载入恶意资源,那可以做的事情也相对比较少一点

你不能不知道的安全性 HTTP headers

Strict Transport Security (HSTS)

HSTS 的全名是 HTTP Strict Transport Security,听过这个 header 的人可能比较少一点,他是用来强制浏览器只能使用安全的 HTTPS 协定跟网站进行连线,而不能使用 HTTP

譬如说很多网站其实用 HTTP 跟 HTTPS 都连得上,但考量到安全性,当然是希望使用者都走 HTTPS。这时只要在 header 裡加上 Strict-Transport-Security: max-age=31536000; includeSubDomains,那在往后的 31536000 秒内(其实就是一年啦XD),只要使用者的浏览器看到这个域名或他的子域名,就会全部改成用 HTTPS 进行连线,真的是很方便呢

也因为现在网站几乎都有 HTTPS 了,所以像平常会用到的 Google、Medium、Facebook 都可以看到 HSTS 的踪迹,只是大家设定的 max-age 稍有不同,比较常看到的大概会是 31536000(一年)、15552000(180 天)这类的数字

你不能不知道的安全性 HTTP headers

X-Content-Type-Options

听过这个 header 的人可能又更少了,在讲这个 header 之前,得先来谈谈什麽是 content sniffing:一般来说浏览器会通过 Content-Type 来判断请求到的资源是什麽类型,像透过 <script src="script.js"> 拿到的 Content-Type 一般都是 text/javascript,因此浏览器看到之后就会拿来执行

你不能不知道的安全性 HTTP headers

但有些网站(尤其是十几二十年前的旧网站)在开发时并没有把 Content-Type 设好,导致某些 JS 档的 Content-Type 是 text/plain,也就是纯文字档。为了让这些网站可以顺利运作,浏览器除了参考 Content-Type 之外,也会做 content sniffing 从档案内容分析是什麽类型,如果分析出是 JS 那就会拿去执行,这样旧网站才不会坏掉

但 sniffing 这个动作看似贴心,却也是一个弱点。譬如说有些网站允许使用者上传资源,那攻击者就可以恶意上传一些有 JS 特性的 JPG 档(这些图片会被浏览器判断成脚本)。接著想办法让这张图片被载入到前端来,导致裡面的恶意脚本被执行,造成 XSS 攻击

为了防止浏览器在那边乱猜资源的 Content-Type 是什麽(而且麻烦的是每个浏览器猜的方式还不太一样),我们要在 headers 裡面加上 X-Content-Type-Options: nosniff 告诉浏览器直接用 header 裡面提供的 Content-Type 就好,不要在那边瞎猜,如此一来就不会再有纯文字、图片被判断成脚本这种事

你不能不知道的安全性 HTTP headers

但也因为加了 nosniff,所以务必要注意各种资源的 Content-Type 有没有设定好,因为浏览器不会帮你猜,如果你真的把 JS、CSS 的 Content-Type 设错,那浏览器就不会把它跑起来,网站看起来也就怪怪的

X-Frame-Options

平常在写网页时,若是想把其他网页的内容拿过来用(下图),可以用 <iframe src="https://website.com"> 把他嵌入进来;反之,若是别人想把我做的网站嵌入到他的网站裡面也是可以的

你不能不知道的安全性 HTTP headers

那这样会有什麽资安疑虑呢?万一有个坏坏网站,他通过 iframe 把气象局网页嵌入进去后,用 CSS 把那个 iframe 调成透明的,然后在透明的 iframe 背后放一些按钮(下图)。那使用者在坏坏网站上点击我很帅、我帅爆时,就会不小心点到气象局的网站,这种攻击就称作 Clickjacking

你不能不知道的安全性 HTTP headers

如果点到的只是气象局网站那不会怎麽样,反正怎麽点也就是那样。但万一被嵌入的是某银行的网站呢?那使用者可能就会被精心设计的按钮给骗到,在无意识的情况下就按了 iframe 裡面的转帐、提款等等按钮

为了要避免这类问题,最好的方法就是加上 X-Frame-Options: deny 这个 header,意思是告诉浏览器说我这个网站不想被嵌入(为了安全起来大部分的银行都会加这个 header)

你不能不知道的安全性 HTTP headers

所以当我想在自己的网站上把玉山银行的页面嵌入进来时,浏览器就会喷出ebank.esunbank.com.tw 不允许在被别的网站嵌入”的错误。因为玉山银行的页面根本不允许被嵌入,也就避免了基于 iframe 的 Clickjacking 攻击

总结

今天介绍了 CSP、HSTS、X-Content-Type-Options 跟 X-Frame-Options 总共四个跟安全性有关的 HTTP headers,这些 headers 不只用起来轻松简单,加上去根本不用十分钟,而且又可以大幅提高安全性,所以已经是网站开发不可缺少的 HTTP headers 了

除了这四个之外其实还有 X-XSS-Protection、Expect-CT、Public-Key-Pins、Feature-Policy 等等很多 header,但因为有些效果没那麽大、有些则是已经被宣佈弃用了,所以这边就暂且不提,有兴趣可以自己到 Owasp Secure Headers 上面看看~


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

https://medium.com/starbugs/m...

交流

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

你不能不知道的安全性 HTTP headers