HTTPS 是 HTTP over Secure Socket Layer,以安全为目标的 HTTP 通道,所以在 HTTPS 承载的页面上不允许出现 http 请求,一旦出现就是提示风险或报错:
Mixed Content: The page at ‘https://www.n360.cn/‘ was loaded over HTTPS, but requested an insecure image ‘http://g.alicdn.com/s.gif’. This content should also be served over HTTPS.
HTTPS改造之后,我们可以在很多页面中看到如下警报: 很多运营对 https 没有技术概念,在填入的数据中不免出现 http 的资源,体系庞大,出现疏忽和漏洞也是不可避免的。
通过 upgrade-insecure-requests 这个 CSP 指令,可以让浏览器帮忙做这个转换。启用这个策略后,有两个变化: 页面所有 HTTP 资源,会被替换为 HTTPS 地址再发起请求; 页面所有站内链接,点击后会被替换为 HTTPS 地址再跳转; 跟其它所有 CSP 规则一样,这个指令有两种方式来启用,需要注意的是 upgrade-insecure-requests 只替换协议部分,所以只适用于 HTTP/HTTPS 域名和路径完全一致的场景。
1、HTTP 响应头方式:
在我们服务器的响应头中加入:
header("Content-Security-Policy: upgrade-insecure-requests");
如nginx的配置
配置nginx,在响应中添加一个响应头:
add_header Content-Security-Policy upgrade-insecure-requests;
配置文件如图:
我们的页面是 https 的,而这个页面中包含了大量的 http 资源(图片、iframe等),页面一旦发现存在上述响应头,会在加载 http 资源时自动替换成 https 请求。
可以查看 google 提供的一个 demo(https://googlechrome.github.io/samples/csp-upgrade-insecure-requests/index.html):不过让人不解的是,这个资源发出了两次请求,猜测是浏览器实现的 bug:
二、标签方式
在页面中的头文件加入 meta 头。
比如:<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
目前支持这个设置的还只有 chrome 43.0,不过我相信,CSP 将成为未来 web 前端安全大力关注和使用的内容。而 upgrade-insecure-requests 草案也会很快进入 RFC 模式。
从 W3C 工作组给出的 example(http://www.w3.org/TR/upgrade-insecure-requests/#examples),可以看出,这个设置不会对外域的 a 链接做处理,所以可以放心使用。