CSRF:为每个请求生成令牌

4 java jsp csrf spring-security

现在,我们每个会话都有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);
    }
Run Code Online (Sandbox Code Playgroud)

并且对于每个请求,

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

using,usings等于比较字符串并返回true或false.

我的问题是,如果我尝试为每个请求生成令牌而没有从会话中获取令牌,会发生什么.比较时,我将从会话中获取并请求.这是个好主意还是遗失了什么?

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

    //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);
Run Code Online (Sandbox Code Playgroud)

Jay*_*ist 5

你想要翻转上面提到的流程.每次比较后,您都应该创建一个新令牌.

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

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

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