XSS 前端防火墙(5): 整装待发
到目前为止,我们把能用前端脚本防御 XSS 的方案都列举了一遍。
尽管看起来似乎很复杂累赘,不过那些是理论探讨而已,在实际中未必要都实现。我们的目标只是为了预警,能发现问题就行,并非要做到滴水不漏的程度。
事实上,HTML5 早已制定了一套浏览器 XSS 解决方案 —— Content Security Policy,并且大多主流浏览器实现了这个标准。
既然我们使用前端脚本重新实现一遍,因此得在各个方面占有优势。
兼容性
CSP 目前主流浏览器大多已支持,IE10、11 支持部分功能。对于 IE10 之前的,当然就束手无策了。如果使用前端脚本实现,可根据浏览器的实际能力进退。
对于第一篇介绍的 DOM-XSS,只要支持标准事件模型即可开启,因此兼容 IE9 完全可行。
事实上,IE8 就已开放了浏览器 API 接口,并支持原生访问器的操作。所以,IE8 是支持钩子程序,并能拦截可疑元素。
考虑到实际中,大多情况不做拦截,仅仅上报日志用以预警。对于这样低的需求,任何版本的浏览器都是完全可行的,甚至连 IE6 也没问题。
由于国内 IE 浏览器仍占有相当一部分比例,因此使用前端脚本的方案,能覆盖到更广的用户群体中。
部署
CSP 是通过 HTTP 头部实现的,策略配置储存在 Content-Security-Policy 这个字段里,因此得在 Web 服务器端进行配置。这对一些使用虚拟主机搭建的中小网站来说,配置起来比较麻烦。
而前端实现只需在页面里插入个脚本就行,完全不用关心后端的部署,修改策略也无需重启服务,维护起来容易的多。
不过,未来 CSP 会支持页面部署,通过 meta 标签即可配置策略,因此实用性会大幅提高。
当然,如今面临的各种问题,最终都能通过标准的完善和时代的进步而消失。所以任何方案都只是在解决当下的问题。
性能
毫无疑问,浏览器原生支持的肯定比模拟出来的更有效率。
之前考虑了各种情况,需安装各种事件和钩子,感觉很是累赘。不过,那只是理论上防御最严密的情况,现实中基本只作预警,并不需监控全开。
作为测试,我们还是考虑最严密的情况。根据前几篇文章探讨的结果,我们做一个原型演示。
为了能线下模拟在线产品,同时做了一个 Chrome 插件,将脚本注入到在线页面里:
页面中使用到的脚本、插件、网络通信等,都在控制台里监控到,并且根据策略匹配显示不同的颜色。
再来看性能影响。尽管我们开启了所有的监控,但初始化消耗的时间,仍可接受。(测试环境 i3 2.3G 的笔记本 Win7 64位)
毕竟,JavaScript 的钩子仅仅是修改变量的字段而已,并非像传统语言那样得修改内存权限等等。
当然,这个页面内容比较少,只能看出脚本初始化的情况。
我们换个内容非常多的页面:
由于嵌套了框架页,在讨论钩子的时候我们提到,新的页面环境也需防御,因此触发了多次『主动防御』的初始化。
『静态扫描』的内容,正是被 MutationObserver 捕获的元素。由于页面内容非常多,静态元素也是随着 HTML 文档边下载边展现的。尽管扫描累计时间并不少,但相对整个页面加载的数秒时间,也基本忽略不计了。
『动态扫描』的内容,则是后期通过脚本创建的。随着滚动条往下拉,扫描次数也逐渐增多。由于我们勾住了 createElement ,理论上说调用会慢一些。不过现实中很少会一口气大量调用该方法的,大多使用模板通过 innerHTML 批量创建。
另外,我们还勾住了 setAttribute 这个常用的方法,统计结果和『访问器钩子』一起纳入在『属性检验』里。不过,现实中大多场合并不需要调用这个方法,毕竟从 attribute 到 property 还得经过一次字符串的解析,能直接用 property 则完全没必要去 setAttribute。
而访问器钩子,只有在修改 script、embed 这些元素的 src 属性时才会触发,这些操作本来就很少,因此属性扫描的额外消耗还是可以忽略的。
策略配置
使用脚本最大的优势就在于,其策略可以灵活配置。规则可以动态产生,匹配也不限模式,通配符或是正则都可以。本来一切都是脚本实现的,何去何从完全也可由脚本决定。
当然,为了更好的适应 CSP 标准,我们尽可能的将策略规范与标准靠近,以便相互兼容。
因为脚本的灵活性,我们不仅支持通配符来匹配站点名,正则表达式也是完全支持。同时为了方便测试,调试控制台里可以动态修改策略。
下面,我们找个存在 XSS 的页面,立即来试验下:
刷新,XSS 执行了:
虽然是非同源执行的,但好歹也算个 XSS。我们就那它来测试。
接着开启我们的防火墙,为可执行模块配上白名单策略。只允许当前站点的资源,其他的则拦截,并且发送报警日志:
出现奇迹的时刻到来了。。。
站外的可疑模块成功拦截了!同时开始发送预警日志到后台。
日志上报
标准的 CSP 中,上报的格式是固定的,并且信息内容也有限。但对于脚本来说,这些都不是问题,随时可以添加想要获得的信息。
你肯定会觉得,上报的数量不会太多,存在漏洞的毕竟只是少数。不过,广义上的 XSS 未必都是由漏洞引起的。
XSS —— Cross Site Script,只要是页面里的站外的脚本,都可以算是。通常情况下只能由漏洞引起,但在一些特殊的场合,任意页面都可能出现站外脚本,例如之前讨论的流量劫持,或是浏览器插件,都是很常见的情况。
所以,我们除了能在线预警外,还能统计各个地区运行商的广告劫持,以及一些网页外挂插件。
当然,想绕过也是很容易的。只要在流量上过滤了我们的防御脚本,或是屏蔽日志发送,我们都是无从得知的。
后记
事实上,最终的方案已上线。尽管只抽样了极少量的用户,但仍传回上百万的预警日志。几乎所有都是广告劫持和浏览器插件,即使存在漏洞暂时也无法得知,我们不可能一个个去分析复现。因此,我们还需一套高效的复现系统,来帮助我们实现自动化的复现工作。
XSS 前端防火墙(5): 整装待发的更多相关文章
- XSS前端防火墙
前一段时间,在EtherDream大神的博客里看到关于XSS防火墙的一系列文章,觉得很有意思.刚好科创要做一个防火墙,就把XSS前端防火墙作为一个创新点,着手去实现了. 在实现过程中,由于各种原因,比 ...
- XSS 前端防火墙 —— 整装待发
到目前为止,我们把能用前端脚本防御 XSS 的方案都列举了一遍. 尽管看起来似乎很复杂累赘,不过那些是理论探讨而已,在实际中未必要都实现.我们的目标只是为了预警,能发现问题就行,并非要做到滴水不漏的程 ...
- XSS 前端防火墙(1):内联事件拦截
关于 XSS 怎样形成.如何注入.能做什么.如何防范,前人已有无数的探讨,这里就不再累述了.本文介绍的则是另一种预防思路. 几乎每篇谈论 XSS 的文章,结尾多少都会提到如何防止,然而大多万变不离其宗 ...
- XSS 前端防火墙 —— 可疑模块拦截
上一篇介绍的系统,已能预警现实中的大多数 XSS 攻击,但想绕过还是很容易的. 由于是在前端防护,策略配置都能在源代码里找到,因此很快就能试出破解方案.并且攻击者可以屏蔽日志接口,在自己电脑上永不发出 ...
- XSS 前端防火墙(2):可疑模块拦截
由于是在前端防护,策略配置都能在源代码里找到,因此很快就能试出破解方案.并且攻击者可以屏蔽日志接口,在自己电脑上永不发出报警信息,保证测试时不会被发现. 昨天提到最简单并且最常见的 XSS 代码,就是 ...
- XSS 前端防火墙 —— 天衣无缝的防护
上一篇讲解了钩子程序的攻防实战,并实现了一套对框架页的监控方案,将防护作用到所有子页面. 到目前为止,我们防护的深度已经差不多,但广度还有所欠缺. 例如,我们的属性钩子只考虑了 setAttribut ...
- XSS 前端防火墙 —— 无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- XSS 前端防火墙(3):无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- XSS 前端防火墙(4):天衣无缝的防护
例如,我们的属性钩子只考虑了 setAttribute,却忽视还有类似的 setAttributeNode.尽管从来不用这方法,但并不意味人家不能使用. 例如,创建元素通常都是 createEleme ...
随机推荐
- python 详解re模块
正则表达式的元字符有. ^ $ * ? { [ ] | ( ).表示任意字符[]用来匹配一个指定的字符类别,所谓的字符类别就是你想匹配的一个字符集,对于字符集中的字符可以理解成或的关系.^ 如果放在字 ...
- WordPress插件:幻灯片Meta Slider
在wordpress中添加幻灯片的方法很简单,通过使用Meta Slider就可以简单地给wordpress添加幻灯片. 插件下载>> 安装后启用插件,根据提示创建幻灯片: 设置幻灯片样式 ...
- Android:Android SDK Manager
Android SDK Manager 包含:Tools(构建工具.编译工具.平台工具等) .各种版本SDK.Extras(安卓知识库和辅助工具) 每个SDK至少包含:1.SDK Plaform 2. ...
- 285. Inorder Successor in BST
题目: Given a binary search tree and a node in it, find the in-order successor of that node in the BST ...
- linux查看内存
cat /proc/meminfo 查看内存,查看最为准确. cat /proc/cpuinfo 察看CPU情况. dmesg | less 这样也可以看到,不过带太多的其他信息了. top也可 ...
- 展讯NAND Flash高级教程【转】
转自:http://wenku.baidu.com/view/d236e6727fd5360cba1adb9e.html 展讯NAND Flash高级教程
- PHP包含文件函数include、include_once、require、require_once区别总结
一.使用语法和简介 1.include() 语法:include(/path/to/filename)include()语句将在其被调用的位置处包含一个文件.包含一个文件与在该语句所在位置复制制定文件 ...
- php实现新闻页面
首页 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8& ...
- lumen 使用 redis缓存
建议修改composer.json require 节点如下: "require": { "php": ">=5.5.9", &quo ...
- sdut2169Sequence(dp)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2169 感觉是有递归思想的 dp[j]表示从1到 ...