【问题标题】:CSRF: Generate token for every requestCSRF:为每个请求生成令牌
【发布时间】:2013-04-25 16:22:30
【问题描述】:

现在,我们每个会话都有 csrf 令牌。并使用隐藏字段添加此令牌 jsp。以下 sn-p 每个会话只给出一个:

token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_NAME);
    if (null==token) {
        token = UUID.randomUUID().toString();
        session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token);
    }

对于每个请求,

//calls the above snippet and this time token will not be null 
String st = CSRFTokenManager.getTokenForSession(request.getSession());
String rt = CSRFTokenManager.getTokenFromRequest(request);

在这里,使用等于比较字符串并返回真或假。

我的问题是,如果我尝试为每个请求生成令牌而不从会话中获取令牌会发生什么情况。在比较时,我会从会话中得到请求。这是个好主意还是遗漏了什么?

我将不使用上面的 sn-ps,而是使用以下

    //for every request generate a new and set in session
    token = UUID.randomUUID().toString();
    session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token);

    //get the token from session and request and compare
    String st = (String) request.getSession().getAttribute("CSRF_TOKEN_FOR_SESSION_NAME");
    String rt = CSRFTokenManager.getTokenFromRequest(request);

【问题讨论】:

  • 您可以生成一个令牌,根本不将其存储在会话中。将其作为隐藏字段添加到表单并作为 cookie。当您收到请求时,比较字段和 cookie 的值。
  • 不确定..但是,我认为 cookie 容易受到 CSRF 攻击
  • @ user1609085 CSRF 令牌的想法是攻击者试图发送“隐藏”请求冒充另一个用户 A。攻击者使用其他网站可以注入一些恶意 javascript 代码,这里很重要是他不能从这个站点发送 cookie 或特殊标头中的令牌(浏览器不允许攻击者这样做),这就是为什么令牌通常放在那里。

标签: java jsp spring-security csrf


【解决方案1】:

您需要翻转上述流程。每次比较后,您应该创建一个新令牌。

token-per-request 的一大缺点是如果用户在浏览器中点击后退按钮:

  • 用户访问Page1并在会话中存储TokenA
  • 用户单击指向 Page2 的链接,提交TokenA。应用在会话中验证TokenA,并为用户提供TokenB
  • 用户点击后退按钮返回到第 1 页,会话信息未更新。
  • Page1 仍然只有TokenA 的信息,用户点击链接或提交表单到Page3 提交TokenA,但会话只知道TokenB
  • 应用认为这是一次 CSRF 攻击

因此,您需要非常注意令牌的更新方式和时间。

【讨论】:

  • 我的应用程序中需要这种类型的配置,请建议我进行这种类型的配置,我是否可以实现。
  • 嗨,我知道这是一篇旧帖子,但我现在也遇到了同样的情况。您能否验证我的理解:1)当用户访问第1页时,String st =(String)request.getSession().getAttribute(“CSRF_TOKEN_FOR_SESSION_NAME”);被调用并且为空。在此字符串之后 rt = CSRFTokenManager.getTokenFromRequest(request);被调用,它为会话属性生成并设置一个新值。比较什么时候完成?
  • 如果用户刷新页面会发生什么?
【解决方案2】:

除了 Jay 建议的解决方案之外,我建议您通过在对客户端的响应中设置各种缓存控制标头来避免缓存您的网页。

【讨论】:

  • 如果没有上下文,我认为您的建议非常糟糕。 Jay描述的流程真的一点都不实用。 GET 请求 99% 的时间不会更新数据,这就是为什么它们会被获取,如果确实如此,那么您的系统设计不佳。因此,您最终只能保护 POST|PUT|DELETE|HEAD... 而对于那些来自表单的人来说,后退按钮的情况在精心设计的应用程序中并不常见。通常在发布表单后重定向,因此在返回浏览器历史记录时无法重新发布表单
猜你喜欢
  • 2012-09-18
  • 1970-01-01
  • 2014-03-05
  • 2014-01-06
  • 2018-11-22
  • 2018-07-29
  • 2012-11-04
  • 2012-05-15
  • 2016-10-15
相关资源
最近更新 更多