【前端安全】JavaScript防http劫持与XSS
作为前端,一直以来都知道HTTP劫持
与XSS跨站脚本
(Cross-site scripting)、CSRF跨站请求伪造
(Cross-site request forgery)。但是一直都没有深入研究过,前些日子同事的分享会偶然提及,我也对这一块很感兴趣,便深入研究了一番。httphijack.js ,欢迎感兴趣看看顺手点个 star ,本文示例代码,防范方法在组件源码中皆可找到。
接下来进入正文。
可以戳我查看DEMO。(打开页面后打开控制台查看 console.log)
点击图中这几个按钮,可以看到如下:
这里我们用到了黑名单匹配,下文还会细说。
可以戳我查看DEMO。(打开页面后打开控制台查看 console.log)
是页面加载一开始就存在的静态脚本(查看页面结构),我们使用 MutationObserver 可以在脚本加载之后,执行之前这个时间段对其内容做正则匹配,发现恶意代码则
removeChild()
掉,使之无法执行。
MDN ,第一句就是:
该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。
虽然不能用,也可以了解一下:
document.addEventListener('DOMNodeInserted', function(e) { var node = e.target; if (/xss/i.test(node.src) || /xss/i.test(node.innerHTML)) { node.parentNode.removeChild(node); console.log('拦截可疑动态脚本:', node); } }, true);
然而可惜的是,使用上面的代码拦截动态生成的脚本,可以拦截到,但是代码也执行了:DOMNodeInserted
顾名思义,可以监听某个 DOM 范围内的结构变化,与 MutationObserver
相比,它的执行时机更早。
但是 DOMNodeInserted
不再建议使用,所以监听动态脚本的任务也要交给 MutationObserver
。
可惜的是,在实际实践过程中,使用 MutationObserver
的结果和 DOMNodeInserted
一样,可以监听拦截到动态脚本的生成,但是无法在脚本执行之前,使用 removeChild
将其移除,所以我们还需要想想其他办法。
可以戳我查看DEMO。(打开页面后打开控制台查看 console.log)
重写 Element.prototype.setAttribute
,就是首先保存原有接口,然后当有元素调用 setAttribute 时,检查传入的 src 是否存在于白名单中,存在则放行,不存在则视为可疑元素,进行上报并不予以执行。最后对放行的元素执行原生的 setAttribute
,也就是 old_setAttribute.apply(this, arguments);
。
上述的白名单匹配也可以换成黑名单匹配。
CSP
《web前端黑客技术揭秘》
使用 Javascript 写的一个防劫持组件,已上传到 Github – httphijack.js,欢迎感兴趣看看顺手点个 star ,本文示例代码,防范方法在组件源码中皆可找到。
另外组件处于测试修改阶段,未在生产环境使用,而且使用了很多 HTML5 才支持的 API,兼容性是个问题,仅供学习交流。
到此本文结束,如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。