- Published on
使用CSP阻止运营商的广告插入劫持
- Authors
- Name
- Will Liu
- @satlxq111
1. 问题背景
万恶的运营商
从 2015 年底开始,频繁发现的 WAP 站点遭到篡改,服务端返回的网页被篡改并插入广告,部分广告还不堪入目,中国移动的 4G 网络还会直接插入其客服入口到页面底部,弹出 App 下载等,更有甚者直接替换 js 内容,导致页面工作不正常。
从篡改的方式来看,大部分属于如下几种:
- 在页面底部插入 script 标签引入广告 js
- 直接插入广告内容到页面
- 劫持正常 js 请求,返回广告内容 js
近两年百度,淘宝,天猫都升级到了 https,可以阻止这类传输过程中的内容篡改,但我们的 https 服务上线还需时日,只能暂时想其他办法。
由于现在发现的大部分还是页面被注入广告 js,所以主要策略是如何阻止广告 js、图片的加载。
2. 什么是 CSP?
内容安全策略 (CSP, Content Security Policy) 是浏览器的一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。
通过在服务端返回的 http 头中增加 csp 头,csp 头中设定不同资源的加载策略,白名单等,限制广告内容的加载。
CSP 1.0 的浏览器支持度已经很好,见caniuse
目前 w3c 已经推出到了 level 2 版本规范,浏览器支持有限。
具体内容可以参考:
3. 实现方式
在服务端由后端动态向返回页面的 http 请求中添加 csp 头, csp 头的具体内容可以通过 ini 配置,wap 整站共用同一个 csp 配置。如果需要临时关闭 csp,或者加入新的域名,可以调整 ini 配置。 前端代码不需要改动。
加入 CSP 后,wap 站返回 http 头类似如下:
Connection:keep-aliveContent-Encoding:gzipContent-Language:zh-CNContent-Security-Policy:default-src * data: blob:;script-src 'self' *.googletagmanager.com *.google-analytics.com *.googleadservices.com *.google.com res.wx.qq.com 127.0.0.1:* 'unsafe-inline' 'unsafe-eval' blob:;style-src * 'unsafe-inline' data:;img-src 'self' *.doubleclick.net *.googletagmanager.com *.google-analytics.com *.googleadservices.com *.google.com res.wx.qq.com 127.0.0.1:* data:Content-Type:text/html;charset=UTF-8Date:Thu, 17 Mar 2016 08:29:53 GMT从上面的规则可以看出,主要控制了两类资源的加载,其它资源类型不限制:
- script-src: 只允许加载网易域内的内容以及统计,微信等的 js。
- img-src: 只允许加载网易域内,或者统计服务域的内容(比如 google 统计服务通过获取图片的方式上传数据)。
所以如果后续增加了新的统计服务,或者图片、JS CDN 服务域名,需要调整此 CSP 规则,否则将被拒绝加载。
4. 实施效果
使用 CSP,可以解决页面被插入外链 JS 劫持的情况,无法覆盖到所有的劫持场景(比如运营商直接篡改 JS 返回内容)。彻底解决内容篡改还是需要上 https 服务。
在 App 端,针对篡改一般发生在页面 html 返回请求中的特点,App 端已经在测试一种新的数据返回机制,让服务端使用 json 的方式返回 html 内容,客户端收到并解析后再提交给 webview 渲染,这样就避免了 html 返回过程中的篡改,该方案也不涉及前端调整,目前还没有上线。
由于此次实施,没有启用 CSP 的拦截报告功能,所以无法直接统计到实际拦截数据。但从目前的使用观察来看,已经可以阻止掉中国移动插入的服务入口,以及部分电信广告插入。