我如何在 java 中安全地实施 CSRF 令牌
How can i securely implement CSRF tokens in java
问题背后的问题:
我试图在我的 java 网络应用程序中防止 csrf 攻击,为了实现它,我尝试实现 X-CSRF-Token
,无论何时发出请求,请求都会像这样传输:
POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67
现在作为攻击者,我试图实现的是,我拦截了 post 请求,而不是攻击令牌,我尝试攻击参数,例如,请参见以下请求:
POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
testX-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67
当我尝试上述请求时,CSRF 令牌实施失败,但我能够成功绕过 csrf 注入,
缓解此类攻击的最佳方法是什么?csrf 注入是否有效?如何优化我的 java 网络应用程序以防止此类攻击?
我是如何实现 java 代码的:
在我的 xml 中:
<http>
<!-- ... -->
<csrf disabled="true"/>
</http>
在我的代码中:
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
}
}
在表单提交时:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
method="post">
<input type="submit"
value="Log out" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
</form>
我也遵循了 here 中提供的推荐方法
,在上述情况下,csrf 失败,缓解措施可能是什么?
根据 spring 的文档,您可以注入自定义 RequestMatcher
来验证 CSRF 令牌的 HTTP 请求。 Spring 为您提供覆盖默认值的功能。
参见第 16.6 节 http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html
class CSRFRequestMatcher implements RequestMatcher{
public boolean matches (HttpServletRequest req){
//Check if request contains valid header name & header value
}
}
问题背后的问题:
我试图在我的 java 网络应用程序中防止 csrf 攻击,为了实现它,我尝试实现 X-CSRF-Token
,无论何时发出请求,请求都会像这样传输:
POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67
现在作为攻击者,我试图实现的是,我拦截了 post 请求,而不是攻击令牌,我尝试攻击参数,例如,请参见以下请求:
POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
testX-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67
当我尝试上述请求时,CSRF 令牌实施失败,但我能够成功绕过 csrf 注入,
缓解此类攻击的最佳方法是什么?csrf 注入是否有效?如何优化我的 java 网络应用程序以防止此类攻击?
我是如何实现 java 代码的:
在我的 xml 中:
<http>
<!-- ... -->
<csrf disabled="true"/>
</http>
在我的代码中:
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
}
}
在表单提交时:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
method="post">
<input type="submit"
value="Log out" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
</form>
我也遵循了 here 中提供的推荐方法 ,在上述情况下,csrf 失败,缓解措施可能是什么?
根据 spring 的文档,您可以注入自定义 RequestMatcher
来验证 CSRF 令牌的 HTTP 请求。 Spring 为您提供覆盖默认值的功能。
参见第 16.6 节 http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html
class CSRFRequestMatcher implements RequestMatcher{
public boolean matches (HttpServletRequest req){
//Check if request contains valid header name & header value
}
}