首页 > 解决方案 > Anti-CSRF 令牌是存储在客户端、服务器端还是两者兼而有之?

问题描述

我正在创建一个带有 Node.js 后端的 React Js 网站。我一直在尝试找出一种用户身份验证实现来防止 CSRF 攻击,但是我真的很困惑在哪里存储 Anti-CSRF 令牌。

我对安全实施的思考过程如下......

  1. 用户提交使用凭据登录的请求。
  2. 凭据经过身份验证。
  3. 服务器创建会话。
  4. 服务器创建 JWT 以用作 Anti-CSRF 令牌。
  5. 服务器将 JWT(Anti-CSRF 令牌)存储在会话存储中。
  6. 服务器向客户端发送响应。
    • 响应具有在客户端的 HttpOnly cookie 中存储会话 ID 的标头。
    • 响应负载包括 JWT(反 CSRF 令牌)。
  7. 客户端收到响应。
  8. 持有会话 ID 的 HttpOnly cookie 存储在客户端。
  9. 客户端将 JWT(Anti-CSRF 令牌)存储在 localStorage 中。

我认为当用户需要请求信息时,客户端可以通过标头或有效负载发送 JWT(Anti-CSRF 令牌),并且由于它是 cookie,会话 ID 将自动发送。然后,服务器可以检查会话存储中是否存在 JWT(Anti-CSRF 令牌)。

我知道 JWT(反 CSRF 令牌)需要在某个时候刷新。

我的困惑是由于在客户端存储了 JWT(反 CSRF 令牌)。我一直在读它应该只存储在服务器上。但如果它只存储在服务器上,它似乎根本没有做任何事情。

我曾考虑同时使用 cookie 和 localStorage,因为似乎如果对服务器的请求需要 HttpOnly cookie 和 localStorage 中的某些内容来发送回“授权”响应,则攻击者需要成功地运行会话并成功实现XSS 攻击获取 Anti-CSRF 令牌。

我最近才开始学习 CSRF 和 XSS,所以我可能完全错了,我的实现中可能存在我遗漏的巨大缺陷。但我的主要问题是……反 CSRF 令牌不需要存储在客户端和服务器上吗?

标签: sessioncookiesjwtxsscsrf

解决方案


它们也被称为“CSRF 令牌”。当客户端请求表单(例如银行登录页面)时,服务器生成令牌并将它们传递给客户端,当客户端填写表单时,客户端将 CSRF 令牌与完成的表单一起传递。服务器验证令牌值,如果匹配,则满足请求。CSRF 令牌以同步器令牌模式存储在服务器端。


推荐阅读