如何在java中防止我的web应用程序出现CSRF(跨站点请求伪造)
我正试图防止我的web应用程序受到CSRF(跨站点请求伪造)的攻击 我跟踪了这个链接 这就是我尝试过的。 为了在Java中实现这一机制,我选择使用两个过滤器,一个用于为每个请求创建salt,另一个用于验证它。由于用户请求和后续应该验证的POST或get不一定按顺序执行,因此我决定使用基于时间的缓存来存储有效salt字符串的列表 第一个过滤器用于为请求生成新的salt并将其存储在缓存中,其编码如下:如何在java中防止我的web应用程序出现CSRF(跨站点请求伪造),java,csrf-protection,Java,Csrf Protection,我正试图防止我的web应用程序受到CSRF(跨站点请求伪造)的攻击 我跟踪了这个链接 这就是我尝试过的。 为了在Java中实现这一机制,我选择使用两个过滤器,一个用于为每个请求创建salt,另一个用于验证它。由于用户请求和后续应该验证的POST或get不一定按顺序执行,因此我决定使用基于时间的缓存来存储有效salt字符串的列表 第一个过滤器用于为请求生成新的salt并将其存储在缓存中,其编码如下: public class LoadSalt implements Filter{ pu
public class LoadSalt implements Filter{
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Assume its HTTP
HttpServletRequest httpReq = (HttpServletRequest)request;
// Check the user session for the salt cache, if none is present we create one
@SuppressWarnings("unchecked")
Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>)
httpReq.getSession().getAttribute("csrfPreventionSaltCache");
System.out.println("Checking cahce befor creating it from Request :csrfPreventionSaltCache: "+csrfPreventionSaltCache);
if(csrfPreventionSaltCache == null)
{
System.out.println("csrfPreventionSaltCache is null have to create new one");
String csrfPreventionfromrequest = (String) httpReq.getSession().getAttribute("csrfPreventionSaltCache");
System.out.println("csrfPreventionfromrequest :"+csrfPreventionfromrequest);
// creating a new cache
csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
.expireAfterAccess(20, TimeUnit.MINUTES).build();
// Setting to gttpReq
httpReq.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
System.out.println("After setting the csrfPreventionSaltCache to HttpReq");
System.out.println("--------csrfPreventionSaltCache------ :"+httpReq.getSession().getAttribute("csrfPreventionSaltCache"));
}
// Generate the salt and store it in the users cache
String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
System.out.println("Salt: "+salt);
csrfPreventionSaltCache.put(salt, Boolean.TRUE);
// Add the salt to the current request so it can be used
// by the page rendered in this request
httpReq.setAttribute("csrfPreventionSalt", salt);
System.out.println("Before going to validate salt checking for salt in request");
System.out.println(" httpReq.getAttribute(csrfPreventionSalt) ----:"+httpReq.getAttribute("csrfPreventionSalt"));
// System.out.println(" httpReq.getSession().getAttribute(csrfPreventionSalt) :----"+httpReq.getSession().getAttribute("csrfPreventionSalt"));
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
}
public类LoadSalt实现过滤器{
public void doFilter(ServletRequest请求、ServletResponse响应、,
FilterChain链)抛出IOException、ServletException{
//假设它是HTTP
HttpServletRequest httpReq=(HttpServletRequest)请求;
//检查用户会话中的salt缓存,如果没有,我们将创建一个
@抑制警告(“未选中”)
缓存csrfPreventionSaltCache=(缓存)
httpReq.getSession().getAttribute(“csrfPreventionSaltCache”);
System.out.println(“在从请求创建cahce之前检查cahce:csrfPreventionSaltCache:+csrfPreventionSaltCache”);
if(csrfPreventionSaltCache==null)
{
System.out.println(“csrfPreventionSaltCache为空,必须创建新的”);
字符串csrfPreventionfromrequest=(字符串)httpReq.getSession().getAttribute(“CSRFPreventionAltCache”);
System.out.println(“csrfPreventionfromrequest:+csrfPreventionfromrequest”);
//创建新缓存
csrfPreventionSaltCache=CacheBuilder.newBuilder().maximumSize(5000)
.expireAfterAccess(20,TimeUnit.MINUTES).build();
//设置为gttpReq
httpReq.getSession().setAttribute(“csrfPreventionSaltCache”,csrfPreventionSaltCache);
System.out.println(“将csrfPreventionSaltCache设置为HttpReq后”);
System.out.println(“--csrfPreventionSaltCache------:”+httpReq.getSession().getAttribute(“csrfPreventionSaltCache”));
}
//生成salt并将其存储在用户缓存中
String salt=RandomStringUtils.random(20,0,0,true,true,null,new SecureRandom());
System.out.println(“Salt:+Salt”);
csrfPreventionSaltCache.put(salt,Boolean.TRUE);
//将盐添加到当前请求以便可以使用
//通过此请求中呈现的页面
httpReq.setAttribute(“csrfPreventionSalt”,salt);
System.out.println(“在验证盐输入请求的盐检查之前”);
System.out.println(“httpReq.getAttribute(csrfPreventionSalt)--:”+httpReq.getAttribute(“csrfPreventionSalt”);
//System.out.println(“httpReq.getSession().getAttribute(csrfPreventionSalt):-----”+httpReq.getSession().getAttribute(“csrfPreventionSalt”);
链式过滤器(请求、响应);
}
public void init(FilterConfig arg0)抛出ServletException{
}
公共空间销毁(){
}
}
web.xml中的映射
<filter>
<filter-name>loadSalt</filter-name>
<filter-class>com.globalss.dnb.monitor.security.LoadSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>loadSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>validateSalt</filter-name>
<filter-class>com.globalss.dnb.monitor.security.ValidateSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>validateSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
加盐
com.globalss.dnb.monitor.security.LoadSalt
加盐
/*
为了在执行安全事务之前验证salt,我编写了另一个筛选器:
public class ValidateSalt implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Assume its HTTP
HttpServletRequest httpReq = (HttpServletRequest) request;
//String salt = (String) httpReq.getSession().getAttribute("csrfPreventionSalt");
String salt =(String) httpReq.getAttribute("csrfPreventionSalt");
System.out.println("I am in ValidateSalt : salt: "+salt);
// Validate that the salt is in the cache
@SuppressWarnings("unchecked")
Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>)
httpReq.getSession().getAttribute("csrfPreventionSaltCache");
if(csrfPreventionSaltCache !=null && salt !=null && csrfPreventionSaltCache.getIfPresent(salt)!=null)
{
// If the salt is in the cache, we move on
chain.doFilter(request, response);
}
else
{
// Otherwise we throw an exception aborting the request flow
throw new ServletException("Potential CSRF detected!! Inform a scary sysadmin ASAP.");
}
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
}
public类ValidateSalt实现过滤器{
public void doFilter(ServletRequest请求、ServletResponse响应、,
FilterChain链)抛出IOException、ServletException{
//假设它是HTTP
HttpServletRequest httpReq=(HttpServletRequest)请求;
//String salt=(String)httpReq.getSession().getAttribute(“csrfPreventionSalt”);
String salt=(String)httpReq.getAttribute(“csrfPreventionSalt”);
System.out.println(“我在ValidateSalt:salt:+salt中”);
//验证salt是否在缓存中
@抑制警告(“未选中”)
缓存csrfPreventionSaltCache=(缓存)
httpReq.getSession().getAttribute(“csrfPreventionSaltCache”);
if(csrfPreventionSaltCache!=null&&salt!=null&&csrfPreventionSaltCache.getIfPresent(salt)!=null)
{
//如果盐在缓存中,我们继续
链式过滤器(请求、响应);
}
其他的
{
//否则,我们将抛出异常以中止请求流
抛出新的ServletException(“检测到潜在的CSRF!!尽快通知可怕的系统管理员”);
}
}
public void init(FilterConfig arg0)抛出ServletException{
}
公共空间销毁(){
}
}
web.xml中第二个文件tr的映射
<filter>
<filter-name>loadSalt</filter-name>
<filter-class>com.globalss.dnb.monitor.security.LoadSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>loadSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>validateSalt</filter-name>
<filter-class>com.globalss.dnb.monitor.security.ValidateSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>validateSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
验证salt
com.globalss.dnb.monitor.security.ValidateSalt
验证salt
/*
配置两个servlet后,所有安全请求都失败:)。为了解决这个问题,我必须在以安全URL结尾的每个链接和表单帖子中添加csrfPreventionSalt参数,该参数包含同名请求参数的值。例如,在JSP页面内的HTML表单中:
<form action="/transferMoneyServlet" method="get">
<input type="hidden" name="csrfPreventionSalt" value="<c:out value='${csrfPreventionSalt}'/>"/>
...
</form>
...
在做了所有这些之后,我试图尝试CSRF,这就是我所做的
您可以用于用户身份验证和授权。默认情况下,从Spring3.2.0版本开始提供支持
您还可以使用RequestMatcher轻松排除不想保护的URL:
public class CsrfSecurityRequestMatcher implements RequestMatcher {
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/unprotected", null);
@Override
public boolean matches(HttpServletRequest request) {
if(allowedMethods.matcher(request.getMethod()).matches()){
return false;
}
return !unprotectedMatcher.matches(request);
}
}
几天前我遇到了同样的问题,我发现了同样的文章 事实上,当我复制和粘贴它的时候,我在想它有多安全 所以,我的第一个想法是真正开始了解什么是CSRF攻击: 明白了之后,我做的第一件事就是破解m