6

现在,我们每个会话都有 csrf 令牌。并使用隐藏字段添加此令牌 jsp。以下代码段每个会话仅提供一个:

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);

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

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

我将不使用上面的代码片段,而是使用以下代码

    //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);
4

2 回答 2

7

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

每个请求令牌的一大缺点是,如果用户在浏览器中点击后退按钮:

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

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

于 2013-05-03T13:30:13.277 回答
-1

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

于 2016-03-15T05:09:13.280 回答