术语表

混合内容 (Mixed Content)

最后核实

定义

混合内容是指通过 HTTPS 加载的页面中,部分脚本、图片、iframe 等子资源仍通过明文 HTTP 加载,削弱了整个页面的安全性。

混合内容指一个通过 HTTPS 交付的页面引用了明文 HTTP 的子资源。浏览器把它分为两类:主动混合内容(脚本、样式表、iframe、fetch/XHR 请求等)能改变整个页面,会被直接拦截;被动混合内容(图片、音频、视频)在当前的 Chrome 和 Firefox 中会被自动改用 HTTPS 重试,失败就不加载。

为什么重要

攻击者只要能篡改其中一个 HTTP 脚本,就能控制加载它的 HTTPS 页面,包括表单和未设置 HttpOnly 的 Cookie。用户看到的是锁形图标消失或出现警告,被拦截的资源加载不出来,页面功能随之出错。常见原因有:模板或 CMS 数据库里写死的 http:// 地址、老旧的第三方组件,以及网站接入 CDN 或 HTTPS 反向代理后,后端仍以为自己跑在 HTTP 上,生成的链接全是 http://。WordPress 站点迁移到 HTTPS 后没有改站点地址,就是典型例子。

例子

查找写死的 HTTP 引用,或者使用混合内容扫描工具:

curl -s https://example.com | grep -oE '(src|href)="http://[^"]+"'

从源头修正链接,再加一道保险,让浏览器自动升级剩余请求:

add_header Content-Security-Policy "upgrade-insecure-requests" always;

常见误区

  • 混合内容只影响锁形图标的显示。 对图片来说如今基本如此,因为浏览器会自动升级;但混合的脚本或 iframe 等于把页面控制权交给了链路上的任何人。
  • 资源所在服务器加个 HTTPS 跳转就行。 浏览器在发出请求之前就拦截了主动混合内容,根本看不到跳转,必须修改页面里的地址。
  • 开了 HSTS 就没有混合内容。 HSTS 只升级发送过该头的主机,第三方的 HTTP 资源不受影响。

延伸阅读