漂流的老妖怪

导航

 

使用Struts2框架开发的后台在防御XSS攻击的时候很多方式都不能用,因为Struts2对请求进行的二次封装有区别。以下针对Struts2的XSS攻击进行拦截过滤防御解决:

Struts2.3

本方案采用struts2的拦截器过滤,将提交上来的参数转码来解决。 
配置struts.xml:

<package name="default" namespace="/"
        extends="struts-default, json-default">
        <!-- 配置拦截器 -->
        <interceptors>
            <!-- 定义xss拦截器 -->
            <interceptor name="xssInterceptor" class="...此处填写拦截器类名"></interceptor>
            <!-- 定义一个包含xss拦截的拦截栈 -->
            <interceptor-stack name="myDefault">
                <interceptor-ref name="xssInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 这个必须配置,否则拦截器不生效 -->
        <default-interceptor-ref name="myDefault"></default-interceptor-ref>
        <action>
        ...此处省略n个action
        </action>
</package>

Java代码,拦截器实现类:

import java.util.Map;
import org.apache.commons.lang3.StringEscapeUtils;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class XssInterceptor extends AbstractInterceptor{

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // TODO Auto-generated method stub
        ActionContext actionContext = invocation.getInvocationContext();
        Map<String, Object> map = actionContext.getParameters();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String value =  ((String[])(entry.getValue()))[0];
            entry.setValue(StringEscapeUtils.escapeHtml4(value));//将提交上来的字符串进行转码
            //System.out.println((entry.getValue()));
        }
        return invocation.invoke();
    }
}

Struts2.5

需要注意的是,根据测试,从Struts2.3升级到Struts2.5并不能平滑升级,也就是说不能向前兼容。 
Apache官方修改了invocation.getInvocationContext().getParameters();接口的实现,原来返回的是一个java.util.Map,现在返回了一个org.apache.struts2.dispatcher.HttpParameters类型的对象,总体来说更加合理。 
2.5版本的拦截器与2.3版本的差异主要在XssInterceptor.java这个类的intercept方法的具体实现,简单测试了一下,应该问题不大。

public class XssInterceptor extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext actionContext = invocation.getInvocationContext();
        HttpParameters parameters  = actionContext.getParameters();
        for (Map.Entry<String,Parameter> entry : parameters.entrySet()) {
            if (!entry.getValue().isMultiple() && entry.getValue().isDefined()){
                if (!entry.getValue().getValue().equals(StringEscapeUtils.escapeHtml4(entry.getValue().getValue()))){
                    entry.setValue(new Parameter.Request(entry.getValue().getName(),StringEscapeUtils.escapeHtml4(entry.getValue().getValue())));
                }
            }
        }
        return invocation.invoke();
    }
}

测试结果:

输入值:

payload:<script>alert(1)</script>

数据库查看入库:


 

经测试,上述方式能够有效防御XSS的攻击。

原文:https://blog.csdn.net/huplion/article/details/49001151

 

posted on 2018-08-14 17:29  漂流的老妖怪  阅读(1415)  评论(0编辑  收藏  举报