Day12-记得要戴安全帽(二)

前言

昨天介绍了 Content Security Policy 跟 HTTP Strict Transport Security 两个 HTTP header,今天紧接着要来介绍另外两个 X 开头的 X-Content-Type-Options 跟 X-Frame-Options,像这类 X 开头的 HTTP header 一开始都是要用来实验看看是不是真的能增加安全性,後来因为逐渐普及也不能再随便乱改,便决定维持这个名字。所以千万不要看到他是 X 开头就觉得他不是标准的 header 哦,他们没改名只是为了向已经写好的网站相容而已~

X-Content-Type-Options

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

img

但有些网站(尤其是十几二十年前的旧网站)在开发时并没有把 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 就好,不要在那边瞎猜,如此一来就不会再有纯文字、图片被判断成脚本这种事

img

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

X-Frame-Options

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

img

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

img

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

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

img

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

小结

今天又介绍了两个比较冷门的 HTTP Header,虽然除了这四个之外其实还有 X-XSS-ProtectionExpect-CTPublic-Key-PinsFeature-Policy 等等很多跟安全性有关的 HTTP header,但因为有些效果没那麽大、有些则是已经被宣布弃用了,所以这边就暂且不提,有兴趣可以自己到 Owasp Secure Headers 上面看看~

如果对於今天的内容有什麽问题的话欢迎在下方留言,没有的话明天就要来说说怎麽在 Node/Go 写的 API server 把这些 header 用上去了~


<<:  Day 22 资料宝石:【Lab】RDS架构 建立自己的第一台云端资料库 (中)

>>:  [DAY19]Ingress-k8s的海姆达尔

RISC-V: I-type 位元运算指令

看到标题一定都猜到了, 相信大家对这几道指令都不陌生,这次实作的就是 ANDI、ORI、XORI, ...

入门魔法 - Event 事件

前情提要 艾草:「好了,总算选取到树上的红色果实了,那我来教你一些简单的火属性魔法事件。」 「咦,我...

[Day14] 传值或传址(上)

JavsScript 的资料型别分成两大类,第一类是基本型别,第二类是物件型别,型别的介绍可以参考前...

【领域展开 04 式】 架站工具的试用决选

货比三家不吃亏,使用前请详阅说明书 继昨天谈到架站工具蛮多种的,认清需求与目标之後,从原本五样工具先...

认识 React Hooks 之二

今天是延续昨天的 Hooks 探索,要学习的是 useReducer 、useCallback、us...