阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

一个前端DOMXSS过滤器

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/rz/2019/1010/116769.html

    最近热衷于刷twitter,各种大牛的东西让我应接不暇,感觉确实新有干货,前几天看到Yosuke发状态了:

    01.jpg

    是发的一个DOMParser处理、过滤html的小程序。想想觉得还是挺新颖的,以前自己也做了一个XssHtml过滤类(http://phith0n.github.io/XssHtml/),但都是基于后端语言的,不能处理前端比如DOMXSS。

    看了他的代码感觉挺好的,思路也是基于白名单的过滤机制,将允许存在的标签和属性列在javascript对象中,遍历DOM后将允许的标签和属性保留,不允许的丢弃。

    我改了改,加了点过滤,做了个类,代码如下:

brush: js;auto-links: false;">function Jsdxss(allows){this.allows = allows || {  "a" : [ "title", "ping", "href", "class", "target", "style" ],  "b" : [ "class", "style" ],  "img" : [ "src", "class", "style" ],  "div" : [ "class", "style"],  "p" : ["class", "style"]}var buildNodes = function( node ){var i, newNode, attributes, child;switch( node.nodeType ){case 1: // ELEMENT_NODEattributes = allows[ node.tagName.toLowerCase() ];if( attributes === undefined ) return undefined;newNode = document.createElement( node.tagName );for( i = 0; i < node.attributes.length; i++ ){if( attributes.indexOf( node.attributes[ i ].name ) != -1 ){switch(node.attributes[ i ].name){case "href": node.attributes[ i ] = _deal_href(node.attributes[ i ]);break;case "style": node.attributes[ i ] = _deal_style(node.attributes[ i ]);break;}newNode.setAttribute( node.attributes[ i ].name, node.attributes[ i ].value );}}for( i = 0; i < node.childNodes.length; i++ ){child = buildNodes( node.childNodes[ i ] );if( child !== undefined ){newNode.appendChild( child );}}return newNode;case 3: // TEXT_NODEreturn document.createTextNode( node.textContent );default:return undefined;}}var _deal_href = function(attr){var href = attr.value;if (href.indexOf("http://") === 0 || href.indexOf("http://") === 0) {attr.value = href;}else{attr.value = "http://" + href;}return attr;}var _deal_style = function(attr){var style = attr.value;var re = /expression/gimstyle = style.replace(/\\/g, ' ').replace(/&#/g, ' ').replace(/\/\*/g, ' ').replace(/\*\//g, ' ');attr.value = style.replace(re, ' ');return attr;}this.filter = function(html, target){try{var parser = new DOMParser();var newDoc = parser.parseFromString( html, "text/html" );}catch(e){var doc = new ActiveXObject ("MSXML2.DOMDocument");var newDoc = doc.loadXML(html);}        var newBody = newDoc.body;    var target = document.getElementById( target );    var i, childeNode;  target.innerHTML = "";for( i = 0; i < newBody.childNodes.length; i++ ){childNode = buildNodes( newBody.childNodes[ i ] );if( childNode !== undefined ){target.appendChild( childNode );}}}}
    使用方法:
brush: js;auto-links: false;">var html = "HTML CODE";(new Jsdxss()).filter(html, "target");

    运行完成后会将过滤后的代码输出在id为target的元素中。

    github:https://github.com/phith0n/Jsdxss

    大家可以在这个页面测试:http://phith0n.github.io/Jsdxss/test.html


相关文章