我有一个典型的 Web 应用程序,其中我的后端基于具有 Spring Security 6.2+ 的 Spring Boot 3.2,而我的前端基于 Angular 13+
根据 SPA 文档的 Spring CSRF 配置,建议使用
XorCsrfTokenRequestAttributeHandler
进行 BREACH 保护。
因此我尝试了解什么是BREACH 攻击以及它如何利用系统。重点是:
为了容易受到攻击,Web 应用程序必须:
- 从使用 HTTP 级压缩的服务器提供服务
- 在 HTTP 响应正文中反映用户输入
- 在 HTTP 响应正文中反映秘密(例如 CSRF 令牌)
据我所知,SPA 应用程序从 HTTP 客户端 cookie 中读取 CSRF 令牌(例如
XSRF-TOKEN
),并将其作为 HTTP 标头(例如 X-XSRF-TOKEN
)发送到服务器,用于不安全的 HTTP 方法。因此,对于 SPA 应用程序来说,第三个要求没有得到满足,因此,如果我们将 CSRF 令牌视为唯一的秘密,那么它们“不会”容易受到 BREACH 攻击。
我的理解正确吗?如果是,那么我们不需要像 Spring 文档推荐的那样为单页应用程序配置 CSRF,而是可以像下面这样配置:
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
CsrfTokenRequestAttributeHandler csrfRequestHandler = new CsrfTokenRequestAttributeHandler();
// By setting the csrfRequestAttributeName to null, the CsrfToken
// must first be loaded to determine what attribute name to use.
// This causes the CsrfToken to be loaded on every request.
// SPA needs csrf token on the first request to the server.
csrfRequestHandler.setCsrfRequestAttributeName(null);
http.csrf(
crfConfigure ->
crfConfigure
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(csrfRequestHandler));
return http.build();
}
CookieCsrfTokenRepository
:您可以实现
CookieCsrfTokenRepository.withHttpOnlyFalse()
来存储CSRF令牌。这允许您的 Angular 应用程序从 cookie 中读取令牌并将其发送回需要保护的请求标头中。
CsrfToken
处理:配置
CsrfTokenRequestAttributeHandler
以处理 CSRF 令牌。该处理程序将确保令牌在需要时可用作请求属性。
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(crfConfigure ->
crfConfigure
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()))
.and()
return http.build();
}
违规攻击
您的 SPA 设置通常不易受到 BREACH 攻击,因为在 HTTP 响应正文中未反映 CSRF 令牌,因此保持谨慎非常重要。
确保不对敏感数据使用 HTTP 压缩。
我的想法此设置平衡了安全性与 SPA 的操作需求,提供强大的 CSRF 保护,而不会引入不必要的复杂性。定期检查您的安全配置。