前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个前端DOMXSS过滤器

一个前端DOMXSS过滤器

作者头像
phith0n
发布2020-10-15 10:12:33
5260
发布2020-10-15 10:12:33
举报
文章被收录于专栏:离别歌 - 信息安全与代码审计

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

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

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

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

代码语言:javascript
复制
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_NODE
			attributes = 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_NODE
			return 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/gim
		style = 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 );
			}
		}
	}

}

    使用方法:

代码语言:javascript
复制
var html = "HTML CODE";
(new Jsdxss()).filter(html, "target");

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档