使用 Spring Security 保护 Web 应用程序免受 CSRF 攻击

Posted

技术标签:

【中文标题】使用 Spring Security 保护 Web 应用程序免受 CSRF 攻击【英文标题】:Protecting web application from CSRF attack using Spring Security 【发布时间】:2019-09-08 13:31:00 【问题描述】:

我正在我的 Web 应用程序中实施 CSRF 保护。

我使用org.springframework.security.web.csrf.CookieCsrfTokenRepository 类来生成 X-XSRF 令牌。此令牌在每个请求的响应中作为 cookie 发送。

UI 组件是部署在不同服务器上的单页应用程序,它会读取此 cookie 并从 cookie 中读取 X-XSRF 令牌并将其设置为所有后续请求中的标头。

Spring 验证收到的 X-XSRF 令牌并允许/拒绝请求。这工作正常。

但是它们是一个约束,这个 X-XSRF cookie 必须是 httpOnlyfalse 以便客户端 javascript 可以读取它。

我们无法读取httpOnlytrue 的cookie。

在 X-XSRF 令牌 cookie httpOnlytrue 的 Web 应用程序中,是否有任何其他替代方法可以保护 Web 应用程序 CSRF。

使用 JavaScript 方法 (document.cookie) 我无法读取 httpOnly 属性设置为 true 的 cookie,请参阅:

How to read a secure cookie using JavaScript Secure and HttpOnly cookies Cross-Site Request Forgery Prevention Cheat Sheet

我无法更改所有 cookie,因为 httpOnly 在 Websphere 中是 false

或者我是否遗漏了一些东西,客户端 JavaScript 可以读取 httpOnly 的 cookie 是 true

【问题讨论】:

【参考方案1】:

见Spring Security Reference:

CookieCsrfTokenRepository

在某些情况下,用户可能希望将CsrfToken 保留在 cookie 中。默认情况下,CookieCsrfTokenRepository 将写入名为XSRF-TOKEN 的cookie,并从名为X-XSRF-TOKEN 的标头或HTTP 参数_csrf 中读取它。这些默认值来自 AngularJS

您可以使用以下内容在 XML 中配置 CookieCsrfTokenRepository

<http>
    <!-- ... -->
    <csrf token-repository-ref="tokenRepository"/>
</http>
<b:bean id="tokenRepository"
    class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
    p:cookieHttpOnly="false"/>

示例显式设置cookieHttpOnly=false。这是允许 JavaScript(即 AngularJS)读取它所必需的。如果您不需要直接使用 JavaScript 读取 cookie 的能力,建议省略cookieHttpOnly=false 以提高安全性。

您可以使用以下方法在 Java 配置中配置 CookieCsrfTokenRepository

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    

示例显式设置cookieHttpOnly=false。这是允许 JavaScript(即 AngularJS)读取它所必需的。如果您不需要使用 JavaScript 直接读取 cookie 的能力,建议省略cookieHttpOnly=false(改用新的CookieCsrfTokenRepository())以提高安全性。

【讨论】:

我同意!!所以看起来如果客户端 java 脚本想要从 cookie 中读取这个 XSRF-TOKEN 并将其作为所有后续请求的标头 X-XSRF-TOKEN 的一部分发送回服务器,以验证请求是否真实有效,XSRF -TOKEN cookie httpOnly 属性必须为 false。

以上是关于使用 Spring Security 保护 Web 应用程序免受 CSRF 攻击的主要内容,如果未能解决你的问题,请参考以下文章

从 Android 调用使​​用 Spring Security 保护的 REST Web 服务

Web服务中的Spring Security CAS实现

Spring Security

仅使用 Spring Security 自定义令牌无状态保护 REST 控制器,同时保持常规状态完整 Web 登录正常工作

使用 Spring Security 保护 REST API

Spring Security 学习总结