首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CSRF保护不适用于Spring安全6

CSRF保护不适用于Spring安全6
EN

Stack Overflow用户
提问于 2022-11-15 14:16:30
回答 3查看 172关注 0票数 3

我将我的项目升级到Spring 3和SpringSecurity6,但是升级后CSRF保护不再起作用。

我使用以下配置:

代码语言:javascript
复制
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(authorize -> authorize
            .anyRequest().authenticated())
        .httpBasic(withDefaults())
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.ALWAYS))
        .csrf(csrf -> csrf
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
        .build();
}

@Bean
public UserDetailsService userDetailsService() {
     UserDetails user = User.builder().username("user").password("{noop}test").authorities("user").build();
     return new InMemoryUserDetailsManager(user);
}

我的网页上只有一个按钮:

代码语言:javascript
复制
<button id="test">Test CSRF</button>

以及以下JavaScript代码:

代码语言:javascript
复制
document.querySelector("#test").addEventListener('click', async function() {
  console.log('Clicked');
  // This code reads the cookie from the browser
  // Source: https://stackoverflow.com/a/25490531
  const csrfToken = document.cookie.match('(^|;)\\s*XSRF-TOKEN\\s*=\\s*([^;]+)')?.pop();
  const result = await fetch('./api/foo', {
    method: 'POST',
    headers: {
      'X-XSRF-Token': csrfToken
    }
  });
  console.log(result);
});

在Spring 2.7.x中,此设置工作良好,但如果我将项目升级到Spring 3和Security 6,则使用以下调试日志得到403个错误:

代码语言:javascript
复制
15:10:51.858 D         o.s.security.web.csrf.CsrfFilter: Invalid CSRF token found for http://localhost:8080/api/foo
15:10:51.859 D   o.s.s.w.access.AccessDeniedHandlerImpl: Responding with 403 status code

我的猜测是,这与#4001的更改有关。但是,我不明白我必须更改代码的内容,或者是否需要异或某些内容。

我确实检查了它是否是由于CSRF令牌的新延迟加载所致,但即使我再次单击该按钮(并验证XSRF-令牌cookie是否已设置),它仍然无法工作。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-11-21 15:37:38

最近,我在参考文档中添加了一节,用于迁移到5.8 (准备迁移到6.0),演示了解决这个问题的方法。

TL;博士见我正在使用AngularJS或其他Javascript框架

这里的问题是AngularJS (以及上面的示例代码)直接使用XSRF-TOKEN cookie。在Security 6之前,这是很好的。但不幸的是,cookie实际上用于持久化原始令牌,而对于Security 6,默认情况下不接受原始令牌。理想情况下,前端框架将能够使用另一个源来获取令牌,例如X-XSRF-TOKEN响应头。

但是,即使使用Security 6,这样的响应头也不会被开箱即出,尽管它可能是一个值得推荐的增强。我还没有建议进行这样的增强,因为Javascript框架在默认情况下无法使用它。

现在,您需要通过配置Security 6以接受原始令牌来解决这个问题,正如上面链接的第一节所建议的那样。该建议允许提交原始令牌,但继续使用XorCsrfTokenRequestAttributeHandler提供请求属性的散列版本(例如,request.getAttribute(CsrfToken.class.getName())request.getAttribute("_csrf")),以防任何东西将CSRF令牌呈现给可能容易被破坏的HTML。

我建议找一个可靠的来源来更彻底地研究违规行为,但不幸的是,我不能声称自己是这样一个消息来源。

我还建议现在关注Security问题,因为一旦社区开始使用Security 6,情况可能会很快发生变化。您可以使用这个过滤器作为跟踪与CSRF相关的问题的一种可能方式。

票数 4
EN

Stack Overflow用户

发布于 2022-11-18 20:26:54

谢谢你这么做!在JHipster + Spring 3应用程序中,我能够使用它解决类似的项目。然而,这个类名似乎最近可能发生了变化。我要用的是:

代码语言:javascript
复制
.csrf(csrf -> csrf
    .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
    .csrfTokenRequestHandler(new ServerCsrfTokenRequestAttributeHandler()))
票数 2
EN

Stack Overflow用户

发布于 2022-11-16 07:01:53

目前,我通过禁用XorCsrfTokenRequestAttributeHandler来解决这个问题,如下所示:

代码语言:javascript
复制
.csrf(csrf -> csrf
    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
    // Added this:
    .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()))

然而,这意味着我很可能很容易受到攻击。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74447118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档