防止XSS攻击的方法-使用白名单过滤html标签

时间:2022-03-27 12:52:59
问题场景:在网页页面的富文本编辑框添加内容是我们常见的操作,在编辑框中可以给内容填色、变字体等等之后,把内容保存到数据库。但是稍微专业的人会通过firebug/fiddler等工具拦截请求,进行修改数据(添加<script>alert(1);</script><input>等标签),提交到数据库保存,之后加载显示数据时浏览器就执行这些标签。所以我们要在后台处理非正常手段输入的标签内容

解决方法一:jsoup工具类
<dependency>
	<groupId>org.jsoup</groupId>
	<artifactId>jsoup</artifactId>
	<version>1.8.3</version>
</dependency>

jsoup 使用一个 Whitelist 类用来对 HTML 文档进行过滤,该类提供几个常用方法:

表 1. 常用方法:
none():只允许包含文本信息
basic():允许的标签包括:a, b, blockquote, br, cite, code, dd, dl, dt, em, i, li, ol, p, pre, q, small, strike, strong, sub, sup, u, ul, 以及合适的属性
simpleText():只允许 b, em, i, strong, u 这些标签
basicWithImages():在 basic() 的基础上增加了图片
relaxed():这个过滤器允许的标签最多,包括:a, b, blockquote, br, caption, cite, code, col, colgroup, dd, dl, dt, em, h1, h2, h3, h4, h5, h6, i, img, li, ol, p, pre, q, small, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, u, ul

如果这五个过滤器都无法满足你的要求呢,例如你允许用户插入 flash 动画,没关系,Whitelist 提供扩展功能,例如 whitelist.addTags("embed","object","param","span","div"); 也可调用 addAttributes 为某些元素增加属性。

用法:Jsoup.clean(content, Whitelist.relaxed());//content:要处理的内容

实例:
//设置白名单,过滤富文本,清除白名单之外的标签;
public static String convertSpecialChar(String content) {
	content = content.trim();
	content = Jsoup.clean(content, Whitelist.relaxed().addAttributes(":all", "style"));
	
	return content;
}

此外,jsoup还有很多强大的功能
参考:
http://871421448.iteye.com/blog/1545996
jsoup 官方网站:http://jsoup.org


解决方法二:org.apache.oro.text.perl.Perl5Util工具类
<dependency>
	<groupId>oro</groupId>
	<artifactId>oro</artifactId>
	<version>2.0.8</version>
</dependency>

实例:
import org.apache.oro.text.perl.*;    
    
class CleanHtml {  
    public static String clean(String html){  
        StringBuffer buffer = new StringBuffer();    
        Perl5Util preg = new Perl5Util();    
        preg.substitute(buffer,"s/<script[^>]*?>.*?<\\/script>//gmi",html);    
        
        //(?# a,/a,img/br ...标签之外,都删除) 
        preg.substitute(buffer,"s#<[/]*?(?!a|img|br|/a|table|/table|tr|/tr|td|/td)[^<>]*?>#abc#gmi",html);     
        /* 
        preg.substitute(buffer,"s/([\r\n])[\\s]+//gmi",html);   
        */  

        html =buffer.toString(); 
        buffer.setLength(0); 
        return html;  
    }  
}