使用CSP阻止运营商插入广告

猪小花1号2018-09-07 13:01

作者:刘新奇


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版本规范,浏览器支持有限。

具体内容可以参考:

w3c 规范

Content Security Policy 介绍


3. 考拉的实现方式

在服务端由后端动态向返回页面的http请求中添加 csp头, csp头的具体内容可以通过服务端配置,wap整站共用同一个csp配置。如果需要临时关闭csp,或者加入新的规则,可以调整服务端配置。 前端代码不需要改动。

加入CSP后,考拉wap站返回http头类似如下:

Connection:keep-alive
Content-Encoding:gzip
Content-Language:zh-CN
Content-Security-Policy:default-src * data: blob:;script-src 'self' *.netease.com *.127.net *.126.net *.163.com *.w3t.cn *.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' *.netease.com *.127.net *.126.net *.163.com *.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-8
Date:Thu, 17 Mar 2016 08:29:53 GMT

从上面的规则可以看出,主要控制了两类资源的加载,其它资源类型不限制:

  • script-src: 只允许加载网易域内的内容以及统计,微信等的js。
  • img-src: 只允许加载网易域内,或者统计服务域的内容(比如google统计服务通过获取图片的方式上传数据)。

所以如果后续增加了新的统计服务,或者图片、JS CDN服务域名,需要调整此CSP规则,否则将被拒绝加载。


4. 实施效果

使用CSP,可以解决页面被插入外链JS劫持的情况,无法覆盖到所有的劫持场景(比如运营商直接篡改JS返回内容)。彻底解决内容篡改还是需要上https服务。

由于此次实施,没有启用CSP的拦截报告功能,所以无法直接统计到实际拦截数据。但从目前的使用观察来看,已经可以阻止掉中国移动插入的服务入口,以及部分电信常见广告插入。


网易云大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者刘新奇授权发布