转载

Java中使用AntiSamy开源项目防御XSS攻击

之前公司有接了一个国土的项目,虽然是内部小项目,但是可能是zhengfu项目竟然找软件测试公司大概测了一下。。。然后出现了以下三种问题:sql注入,XSS攻击,接口访问频率。下面是解决XSS攻击。

研究:

一开始的想法是,弄个过滤器把那些关键字过滤掉不就好了,例如script、eval、document等等,确实网上也有这些例子。可参考此博客https://www.cnblogs.com/myyBlog/p/8890365.html

但是人家可是请专业的软件测试工程师测试的,我这么混过去肯定是不行滴,上面的主要只是简单地过滤掉用户的输入参数,而且过滤得非常的不全面,可能还有很多方面的攻击呢?然后继续的百度找找有没有此方面的开源项目。结果真的找到了一个,就是AntiSamy,OWASP的一个开源项目,通过对用户输入的 HTML / CSS / JavaScript 等内容进行检验和清理,确保输入符合应用规范。AntiSamy被广泛应用于Web服务对存储型和反射型XSS的防御中。这个就相当的强大了啊。

方案:

参考上面的博客的做法:弄一个过滤器XSSFilter,拦截所有路径。再使用HttpServletRequestWrapper来装饰一下HttpServletRequest,已达到XSS清洗来防御XSS攻击。嗯,就这么大概了,网友真强大~

开工:

1、引入Maven依赖:

<!– OWASP AntiSamy 防止XSS攻击–>

<dependency>

<groupId>org.owasp.antisamy</groupId>

<artifactId>antisamy</artifactId>

<version>1.5.5</version>

</dependency>

2、策略文件:

Maven下载下来的依赖里面是带有策略文件,之前试过前一点的版本例如1.5.3好像是没有的。下面我使用的策略文件将是antisamy-ebay.xml,毕竟eBay 是当下最流行的在线拍卖网站之一,防御策略肯定是非常好的。关于AntiSamy的策略文件的详解大家可以去搜一下,毕竟可能以后要改里面的处理规则呢。

Java中使用AntiSamy开源项目防御XSS攻击

3、怎么使用AntiSamy:

想当的简单,首先要指定策略文件生成Policy,然后新建AntiSamy,再对需要进行XSS清洗的内容进行扫面即可。

String xsshtml = “hyf<script>alert(1)</script>”;

Policy policy = Policy.getInstance(“antiSamyPath”);

AntiSamy antiSamy = new AntiSamy();

CleanRequests cr = antiSamy.scan(xsshtml,policy);

xsshtml = cr.getCleanHTML(); //清洗完的

4、创建XssFilter实现Filter接口然后重新doFilter方法:

因为我们对用户的每次请求都进行拦截清洗,清洗完才能真正地调用Controller的方法,所以我们用到的是过滤器而不是拦截器。因为Filter是一个典型的过滤链,可以用来对 HttpServletRequest 进行预处理,或者是对 HttpServlerResponse 进行后处理。

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

/**

*

*@author howinfun

*@date 2018/10/23

*@company DM

*@version 1.0

*/

public class XssFilter implements Filter {

private FilterConfig filterConfig;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest)servletRequest;

/* filterChain.doFilter(new XssHttpServletRequestWrapper2(request),servletResponse);*/

filterChain.doFilter(new XssHttpServletRequestWrapper(request),servletResponse); //包装request,在里头进行XSS清洗

}

@Override

public void destroy() {

this.filterConfig = null;

}

}

5、新建一个自定义 HttpServletRequest 包装类 XssHttpServletRequestWrapper ,继承 HttpServletRequestWrapper 类:

对getParameter( String param)、getParameterValues( String param)以及 getHeader( String param) 等方法进行重写,在重写里头都进行一遍全方位清洗。

import org.apache.commons.lang.StringEscapeUtils;

import org.jeecgframework.web.appconfig.util.StringUtils;

import org.owasp.validator.html.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import java.util.Iterator;

import java.util.Map;

/**

* @desc 基于AntiSamy的XSS防御

* @author howinfun

* @date 2018/10/23

* @company DM

* @version 1.0

*/

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

//AntiSamy使用的策略文件

private static Policy policy = null;

static {

//指定策略文件,策略文件记得放在classpath下

String antiSamyPath = XssHttpServletRequestWrapper.class.getClassLoader().getResource(“antisamy-ebay.xml”).getFile();

System.out.println(“policy_filepath:”+antiSamyPath);

if(antiSamyPath.startsWith(“file”)){

antiSamyPath = antiSamyPath.substring(6);

}

try {

policy = Policy.getInstance(antiSamyPath);

} catch (PolicyException e) {

e.printStackTrace();

}

}

public XssHttpServletRequestWrapper(HttpServletRequest request) {

super(request);

}

/**

* @desc Header为空直接返回,不然进行XSS清洗

* @author howinfun

* @date 2018/10/24

*

*/

@Override

public String getHeader(String name) {

String value = super.getHeader(name);

if(StringUtils.isEmpty(value)){

return value;

}

else{

String newValue = cleanXSS(value);

return newValue;

}

}

/**

* @desc Parameter为空直接返回,不然进行XSS清洗

* @author howinfun

* @date 2018/10/24

*

*/

@Override

public String getParameter(String name) {

String value = super.getParameter(name);

if(StringUtils.isEmpty(value)){

return value;

}

else{

value = cleanXSS(value);

return value;

}

}

/**

* @desc 对用户输入的参数值进行XSS清洗

* @author howinfun

* @date 2018/10/24

*

*/

@Override

public String[] getParameterValues(String name) {

String[] values = super.getParameterValues(name);

if (values != null) {

int length = values.length;

String[] escapseValues = new String[length];

for (int i = 0; i < length; i++) {

escapseValues[i] = cleanXSS(values[i]);

}

return escapseValues;

}

return super.getParameterValues(name);

}

@SuppressWarnings(“rawtypes”)

public Map<String,String[]> getParameterMap(){

Map<String,String[]> request_map = super.getParameterMap();

Iterator iterator = request_map.entrySet().iterator();

System.out.println(“request_map”+request_map.size());

while(iterator.hasNext()){

Map.Entry me = (Map.Entry)iterator.next();

//System.out.println(me.getKey()+”:”);

String[] values = (String[])me.getValue();

for(int i = 0 ; i < values.length ; i++){

System.out.println(values[i]);

values[i] = cleanXSS(values[i]);

}

}

return request_map;

}

/**

* @desc AntiSamy清洗数据

* @author howinfun

* @date 2018/10/24

*

*/

private String cleanXSS(String taintedHTML) {

try{

AntiSamy antiSamy = new AntiSamy();

CleanResults cr = antiSamy.scan(taintedHTML, policy);

taintedHTML = cr.getCleanHTML();

return taintedHTML ;

}catch( ScanException e) {

e.printStackTrace();

}catch( PolicyException e) {

e.printStackTrace();

}

return taintedHTML;

}

}

6、在web.xml对新建的Filter进行注册。

<!– 防止XSS攻击 –>

<filter>

<filter-name>XSSFilter</filter-name>

<filter-class>org.jeecgframework.core.filter.XssFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>XSSFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

7、接下来进行测试:

简单的测试是否能过滤掉script标签及里面的内容。这个上传的gif不动的,我就不放了,结果肯定是可以过滤掉滴。

8、继续测试:

我继续测试其他接口,测试了一个之前自己做的通用API,发现传回来的JSON数据出现了问题,原来的双引号被转换为&quot。还测试到&nbsp;被转成乱码了。。。所以我们必须在清洗完后进行进一步处理,将这两个问题给自己解决掉。

/**

* @desc AntiSamy清洗数据

* @author howinfun

* @date 2018/10/24

*

*/

private String cleanXSS(String taintedHTML) {

try{

AntiSamy antiSamy = new AntiSamy();

final CleanResults cr = antiSamy.scan(taintedHTML,policy);

//AntiSamy会把“&nbsp;”转换成乱码,把双引号转换成”&quot;” 先将&nbsp;的乱码替换为空,双引号的乱码替换为双引号

String str = StringEscapeUtils.unescapeHtml(cr.getCleanHTML());

str = str.replaceAll(antiSamy.scan(“&nbsp;”,policy).getCleanHTML(),””);

str = str.replaceAll(antiSamy.scan(“/””,policy).getCleanHTML(),”/””);

return str;

}catch( ScanException e) {

e.printStackTrace();

}catch( PolicyException e) {

e.printStackTrace();

}

return taintedHTML;

}

原文链接:https://blog.csdn.net/Howinfun/article/details/83414262

原文  http://www.iigrowing.cn/java_zhong_shi_yong_antisamy_kai_yuan_xiang_mu_fang_yu_xss_gong_ji.html
正文到此结束
Loading...