【问题标题】:Is it necessary to generate anti-XSRF/CSRF token in server side?是否需要在服务器端生成 anti-XSRF/CSRF 令牌?
【发布时间】:2020-10-16 22:13:23
【问题描述】:

几乎所有关于反 CSRF 机制的文档都指出 CSRF 令牌应该在服务器端生成。但是,我想知道是否有必要。

我想在这些步骤中实现anti-CSRF:

  1. 没有服务器端生成的 CSRF 令牌;

  2. 在浏览器端,在每次提交 AJAX 或表单时,我们的 JavaScript 都会生成一个随机字符串作为令牌。此令牌在实际 AJAX 或表单提交发生之前写入 cookie csrf;并且令牌作为 _csrf 添加到参数中。

  3. 在服务器端,每个请求都应该有 cookie csrf 和提交的参数 _csrf。比较这两个值。如果它们不同,则表示这是一次 CSRF 攻击。

服务器端不需要下发CSRF token,只做检查即可;并且令牌完全在浏览器端生成。当然,这只是针对反 CSRF 的。服务器端应该有验证过程来验证用户ID。

这听起来是 CSRF 的有效解决方案,但我不确定为什么没有关于这种方法的文档。

这个anti-CSRF机制有问题吗?

【问题讨论】:

    标签: security web csrf csrf-protection


    【解决方案1】:

    据我了解,您要做的是在客户端创建反 CSRF,将其存储在 cookie 中并将其添加为请求参数,因此当服务器读取您的请求时,只需验证你的 CSRF 令牌 cookie 和参数匹配,它决定它是否是一个有效的请求。

    在服务器端生成防伪令牌的原因是服务器将创建该令牌并​​且只有服务器知道正确的值,所以如果该参数在客户端被轻微篡改,它不会与存储在服务器中的相同,这足以将请求标记为跨站点请求伪造攻击。 任何客户端生成的数据都可能被攻击者篡改,因此,您不能依赖该信息,例如,在您的方法中,您在客户端创建一个随机值并将该值分配给您的 CSRF cookie 和您的 _csrf 参数,假设您的值为“h246drvhd4t2cd98”,但由于您只是验证来自客户端的 2 个变量是否具有相同的值,攻击者可以轻松地创建他的 CSRF cookie 和变量像“I'mByPassingThis”这样的值,您的服务器会将其标记为有效请求,因此您根本没有获得安全性。 另一方面,如果令牌是在服务器中生成的,攻击者无法知道预期值,并且每个请求的预期值都会有所不同,因此攻击者的最佳方法是尝试猜测它,这应该几乎是不可能的,除非您在服务器端使用可预测的随机数生成器。

    另外,如果你想创建自己的防伪令牌机制,你需要考虑使用加密安全的伪随机数生成器,但老实说,你不应该为此烦恼,因为当前的服务器生成过程正是你所需要的(假设你的框架有一个内置的机制,如果没有,那么你仍然需要确保你使用加密安全的伪随机数生成器来生成你的防伪令牌) .

    切记永远不要相信用户提交的信息。由于它总是可以被篡改,因此您总是需要在服务器端执行双重检查,在这种情况下,在服务器中生成您的防伪令牌可以让您双重检查以验证完整性提交了防伪令牌。

    【讨论】:

    • an attacker can easily just create his CSRF cookie 无法为另一个域伪造 cookie,如何实现这一点?
    • 防伪令牌是一个随机数。每次重新加载页面时都必须生成一个新令牌,因此即使攻击者伪造了自己的防伪令牌,它仍然需要与服务器为该请求生成的令牌相匹配,并且只要您已经使用安全的方法而不是可预测的方法创建该令牌,例如在每次请求时将整数加一,攻击者应该无法预测您为每个请求生成的新防伪令牌。跨度>
    • 我完全同意你的看法。但我的问题是关于您所说的攻击者可以伪造 Cookie 的声明。我不确定是否有可能,即使使用 javascript 查询,您也不能为另一个域设置具有仲裁值的 cookie?
    • 哎呀,你是对的。我认为当我写那个答案时,我主要关注的是 POST CSRF,攻击者可以在其中发送一个 cookie 连同请求,以及正文中的 _csrf 参数。这意味着他可以完全控制它们(不需要将其写入网站的 cookie,而只需通过 JSONP 或任何那些“技巧”将其发送到他的 AJAX 请求中,以使同源策略更加灵活),但我我不确定这是否会覆盖请求中的原始网站 cookie、覆盖会话 cookie 并破坏 CSRF 攻击的目的。
    • @EstebanCervantes 我不熟悉其他网站能够为不同域附加自己的 cookie 的任何技巧。你能详细说明一下吗?
    【解决方案2】:

    我建议使用这种方法,我在一个大型项目中使用过:

    发件人:https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers

    自定义请求标头的使用

    添加 CSRF 令牌、双重提交 cookie 和值、加密令牌或其他涉及更改 UI 的防御措施通常很复杂或有其他问题。另一种特别适合 AJAX 或 API 端点的防御措施是使用自定义请求标头。这种防御依赖于同源策略 (SOP) 限制,即只有 JavaScript 可以用于添加自定义标头,并且只能在其源中。默认情况下,浏览器不允许 JavaScript 使用自定义标头进行跨源请求。 如果您的系统是这种情况,您可以简单地验证所有服务器端 AJAX 端点上是否存在此标头和值,以防止 CSRF 攻击。这种方法具有通常不需要更改 UI 和不引入任何服务器端状态的双重优势,这对 REST 服务特别有吸引力。如果愿意,您可以随时添加自己的自定义标头和值。 这种技术显然适用于 AJAX 调用,您仍然需要使用本文档中描述的方法(例如令牌)来保护标签。此外,CORS 配置也应该是健壮的,以使该解决方案有效地工作(因为来自其他域的请求的自定义标头会触发飞行前 CORS 检查)。

    因此,您可以使用请求标头参数存储并发送到服务器,而不是通过请求正文参数发送令牌。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-17
      • 2015-02-07
      • 2014-01-05
      • 1970-01-01
      • 2015-05-14
      • 2012-12-06
      • 2019-12-14
      • 2021-02-15
      相关资源
      最近更新 更多