互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的资源类型。例如:"text/html"代表html文档,"image/png"是PNG图片等等。然而,有些资源的Content-Type是错的或者还未定义。这时,某些浏览器会启用MIME-sniffing(MIME嗅探)来猜测该资源的类型,解析内容并执行。

我们假设,有个网站错误的将HTML文档的后缀改为.js,浏览器可以通过自身的MIME嗅探找出这个错误,并将其解释为HTML文档执行。能够找出文件后缀名错误的浏览器在这个时候干了好事。

这种MIME嗅探也容易被攻击者利用,帮攻击者“干好事”。假设一名攻击者先在本地创建了一个.txt文档,在这个文档里面写上一些JavaScript代码,然后再将这文档的文件后缀名改为.jpg,最后再上传到一些只校验文件后缀名的网站。攻击者再通过某些方式让浏览器加载这个“图片”,浏览器会通过自身的MIME嗅探将这个文件解释为JavaScript文件,并按照JavaScript文件的方式执行。

总的来说,这种功能有利也有弊。但这种功能总的来说容易为XSS提供可能性。所以如果你知道你的服务器在干什么的话(保证Content-Type字段不会错误),那么你就可以发送一个标头让浏览器不要MIME嗅探,这个标头就是X-Content-Type-Options: nosniff

你可以在PHP文档里面添加这么一行代码来解决问题。

header("X-Content-Type-Options:nosniff");

当然,Cloudflare也想到了这个问题。Cloudflare用户可以在SSL/TLS-边缘证书-HSTS设置找到无嗅探标头,并将其开启。

发送这个标头之后,可能会出现一些问题。因为发送这个标头之后,浏览器就不会帮你找出错误了。

HTTP协议安全头部X-Content-Type-Options引入的问题

什么是MIME嗅探?

除了X-Content-Type-Options这个可以保护安全的标头之外,我们之前还介绍过HSTS标头