您的位置:首页 > 编程语言 > Java开发

Struts2 过滤CSRF攻击的一种解决方案

2015-11-04 18:00 387 查看
CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站?的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

它的防御方案包括如下四种:

1.检查http referer是否来自同一个域

2.限制session cookie的生命周期

3.验证码

4.使用token

在struts下自带了许多标签库

其中就有 s:token ,这个可以生成一次性token,把这个标签放在 s:form 里面可以在提交的时候自动带上token值;

<s:form action="login.action">
<s:token name="token"></s:token>
<s:fielderror name="errorInfo"></s:fielderror>
<s:textfield name="username" key="user"></s:textfield>
<s:textfield name="password" key="pass"></s:textfield>
<s:submit key="login"></s:submit>
</s:form>


然后在struts.xml的对应的action中引用就好了

<param name="excludeMethods">....</param> //这里可以配置token拦截器的排队方法


<interceptor-ref name="token">
param name="excludeMethods">....</param> //这里可以配置token拦截器的排队方法
</interceptor-ref>
<result name=“invaild.token">/***.jsp</result>


一般情况下这个拦截器就配置完了

但是这个拦截器会把这个action的post 方法和get方法同时拦截掉。

如果我们只需要拦截post方法的请求应该怎么处理呢?

在这里我们自己实现一个拦截器只拦截post方法

实现如下

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.TokenInterceptor;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class CsrfInterceptor extends AbstractInterceptor{

@Override
public String intercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
ActionContext actionContext = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest)actionContext.get(ServletActionContext.HTTP_REQUEST);
if (request.getMethod().equals("GET")) {
return invocation.invoke();
}
String tokenName = request.getParameter("struts.token.name");
if (tokenName == null) {
return "invalid.token";
}
String token = request.getParameter(tokenName);
if (token == null) {
return "invalid.token";
}
String correctToken = (String) request.getSession().getAttribute("struts.tokens." + tokenName);
if (token.equals(correctToken)) {
actionContext.getSession().put("struts.tokens" + tokenName , null);
return invocation.invoke();
}else {
return "invalid.token";
}
}
}


我们可以用配置一般拦截器的方法配置此拦截器,在此不再叙述。

需要注意的一点是,须在struts.xml下 action标签下配置此项

<result name="invalid.token">jsp/tokenError.jsp</result>


表示token值验证失败后的处理情况,具体实现看实际项目的需要
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: