XSS 前端防火墙?内联事件拦截
作者:网络转载 发布时间:[ 2014/7/9 14:40:10 ] 推荐标签:XSS 安全测试工具
尽管按钮上直接绑了一个内联的事件,但事件模型并不买账,仍然得按标准的流程走一遍。capture,target,bubble,模型是那样固执。
不过,把那行注释的代码恢复,结果只剩 capture 了。这个简单的道理大家都明白,也没什么好解释的。
但仔细揣摩下,这不是『主动防御』的概念吗?捕获程序运行在内联事件触发之前,并且完全有能力拦截之后的调用。
上面的 Demo 只是不假思索拦截了所有的事件。如果我们再加一些策略判断,或许更明朗了:
<button onclick="console.log('xss')">CLICK ME</button>
<script>
document.addEventListener('click', function(e) {
console.log('bubble');
});
document.addEventListener('click', function(e) {
var element = e.target;
var code = element.getAttribute('onclick');
if (/xss/.test(code)) {
e.stopImmediatePropagation();
console.log('拦截可疑事件:', code);
}
}, true);
</script>
Run
|
我们先在捕获阶段扫描内联事件字符,若是出现了『xss』这个关键字,后续的事件被拦截了;换成其他字符,仍然继续执行。同理,我们还可以判断字符长度是否过多,以及更详细的黑白名单正则。
怎么样,一个主动防御的原型诞生了吧。
不过,上面的片段还有个小问题,是把事件的冒泡过程也给屏蔽了,而我们仅仅想拦截内联事件而已。解决办法也很简单,把 e.stopImmediatePropagation() 换成 element.onclick = null 可以了。
当然,目前这只能防护 onclick,而现实中有太多的内联事件。鼠标、键盘、触屏、网络状态等等,不同浏览器支持的事件也不一样,甚至还有私有事件,难道都要事先逐一列出并且都捕获吗?是的,可以都捕获,但不必事先都列出来。
因为我们监听的是 document 对象,浏览器所有内联事件都对应着 document.onxxx 的属性,因此只需运行时遍历一下 document 对象,即可获得所有的事件名。
<img src="*" onerror="console.log('xss')" />
<script>
function hookEvent(onevent) {
document.addEventListener(onevent.substr(2), function(e) {
var element = e.target;
if (element.nodeType != Node.ELEMENT_NODE) {
return;
}
var code = element.getAttribute(onevent);
if (code && /xss/.test(code)) {
element[onevent] = null;
console.log('拦截可疑事件:', code);
}
}, true);
}
console.time('耗时');
for (var k in document) {
if (/^on/.test(k)) {
//console.log('监控:', k);
hookEvent(k);
}
}
console.timeEnd('耗时');
</script>
Run
|
现在,无论页面中哪个元素触发哪个内联事件,都能预先被我们捕获,并根据策略可进可退了。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11