当我们打开一个网页,经常会弹出一堆格格不入的小广告,像牛皮鲜一样,不堪入目;打开的是A网站,莫名其妙却被跳转至B网站;明明想下的是A软件,下载安装后却是B软件…
—— 我的电脑中毒了?
—— 错!你的互联网流量被劫持,被蹂躏了!
—— ???
——请看下面分解!
运营商劫持的目的就是为了带来源源不断的收入。
劫持的技术
- DNS劫持:DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。——百度百科《DNS劫持》
- HTTP劫持:在用户的浏览器连上被访问的网站服务器,发送了HTTP请求后,运营商的路由器会首先收到此次HTTP请求,之后运营商路由器的旁路设备标记此TCP连接为HTTP协议,之后可以抢在网站服务器返回数据之前发送HTTP协议的302代码进行下载软件的劫持,浏览器收到302代码后就会跳转到错误的软件下载地址下载软件了,随后网站服务器的真正数据到达后反而会被丢弃。或者,旁路设备在标记此TCP连接为HTTP协议后,直接返回修改后的HTML代码,导致浏览器中被插入了运营商的广告,随后网站服务器的真正数据到达后最终也是被丢弃。——月光博客
劫持的效果分为两种
- 跳转劫持(访问A网站却跳到B网站)
- 内容劫持(加入广告,替换链接)
劫持原因
根本原因在于HTTP协议本身的一些安全缺陷
HTTP缺陷
- 明文传输
- 不验证身份
- 没有数据完整性校验
有效的解决劫持的HTTPS
- 内容加密 让监听者拿到消息也看不懂
- 证书 用一个权威的机构(CA)和证书来证明通信双方的身份
- 完整性校验
前端劫持的对策
——投诉增值业务部门进而投诉工信部?
——NO!费时费力,只是杯水车薪之位,大多不能完全解决问题!
那么作为前端,我们能做些什么?
劫持对策
302跳转或劫持为只含跳转代码的内容
无解,因为不能载入我们的页面js注入,以document.write/document.writeln方式插入恶意JS文件
简单粗暴,不太优雅,却有效,将document.write重写为空函数1
2
3
4
5
6
7
8
9
10
11var oriDocwrite = document.write;
var docWrite = function (str) {
if (oriDocwrite.apply) {
oriDocwrite.apply(document, arguments);
} else {
oriDocwrite(str);
}
};
document.write = function (str) {
//这里可记LOG用于统计
}对于iframe的情况,要检测非常简单,只需要比较self和top是否相同。
1
2
3
4
5
6
7
8
9
10
11
12<style>
html{
display: none;
}
</style>
<script>
if( self == top ) {
document.documentElement.style.display = 'block' ;
} else {
top.location = self.location ;
}
</script>更多视具体情况而定
主动探测是否存在劫持可能性
- 监控插入页面的JS文件
- 在页面加载完成后,按某种策略(如散列在小范围定次定量定节奏)遍历DOM中的Script标签
- 利用MutationObserver(参见: 《JavaScript 标准参考教程》阮一峰 )监视DOM变动。
劫持始终“野火烧不尽”,祈祷互联网世界和平。