FlawOpen

flawopen.com/XSS/Content-type sniffing

MIME 嗅探 XSS:MIME 混淆如何影响浏览器

参考页面
简要结论

浏览器根据响应的 Content-Type 决定如何处理字节。如果应用以缺失或错误的类型提供用户可控文件,MIME 嗅探可能改变部分响应的处理方式。应发送正确类型和 X-Content-Type-Options: nosniff,并将上传文件与应用 origin 隔离。该响应头降低一种浏览器解释风险;它不会清理文件,也不能代替上传控制措施。

上传文件如何跨越文档边界

假设应用接受用户上传,并从已认证的自身 origin 提供文件,但 Content-Type 缺失或不匹配。如果浏览器将响应解释为 HTML 文档,文件中的标记就可能在站点 origin 下生效。用户打开文件时,这会产生存储型 XSS 或内容混淆风险。扩展名和上传请求声称的媒体类型都不能证明字节的实际格式。

明确设置类型并隔离下载

有风险——使用含糊响应头内联提供用户上传内容
HTTP/1.1 200 OK
Content-Type: application/octet-stream
// 缺少 X-Content-Type-Options
// 与已认证应用使用相同 origin
更安全——正确类型、nosniff 与隔离下载
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename="download.txt"

使用服务器选择且与字节内容相符的 Content-Type,不要照搬上传者声明的类型。X-Content-Type-Options: nosniff 会对文档响应禁用 MIME 嗅探,并阻止 MIME 类型错误的脚本或样式请求。它不是通用 XSS 修复:将上传文件放在单独的 origin,下载时优先使用 Content-Disposition: attachment,并执行大小、授权和文件验证规则。对于图片或其他内联媒体,返回已验证的媒体类型,并测试浏览器实际收到的响应。

常见问题

nosniff 能让任意上传文件都安全可用吗?

不能。它控制浏览器的 MIME 解释以及脚本/样式请求检查,但不会验证或清理文件、纠正错误的 Content-Type,也不会隔离同源上传。对不可信文件使用独立 origin 和附件下载。

参考资料

另请参阅 XSS 跨站脚本攻击(CWE-79):原理与各编程语言的防护方法 — flawopen.com CSP 与输出转义:两者都需要吗? React 的 dangerouslySetInnerHTML 安全吗? DOMPurify 足以保护 innerHTML 吗? Markdown 渲染能防御 XSS 吗? Svelte 默认能防止 XSS 吗? 上传 SVG 有 XSS 风险吗?