csrf 攻击和双重提交的 cookie

Posted

技术标签:

【中文标题】csrf 攻击和双重提交的 cookie【英文标题】:csrf attacks and double submitted cookie 【发布时间】:2012-07-16 02:57:37 【问题描述】:

以下引用来自http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html

当用户访问一个网站时,该网站应该生成一个 (密码强)伪随机值并将其设置为 cookie 在用户的机器上。该网站应要求提交每个表单 包括这个伪随机值作为一个表单值,也作为一个 饼干价值。当一个 POST 请求被发送到站点时,该请求 仅当表单值和 cookie 值时才应被视为有效 是相同的。当攻击者代表用户提交表单时,他 只能修改表单的值。攻击者无法读取任何 从服务器发送的数据或修改 cookie 值,每个同源 政策。这意味着虽然攻击者可以发送他想要的任何值 使用表单,他将无法修改或读取存储在 饼干。由于 cookie 值和表单值必须是 同样,攻击者将无法成功提交表单,除非 他能够猜测伪随机值。

上述方法通过比较cookie和表单中的伪随机值来防止CSRF攻击。但是,为什么还需要将值与表单一起返回?我假设表单和 cookie 都具有它们返回到服务器的相同加密值。服务器通过解密该值来验证它。

因此,即使该值仅由 cookie 返回,服务器也可以对其进行解密并验证请求。用表单返回加密值的目的是什么?

【问题讨论】:

【参考方案1】:

无论请求是由原始站点还是第三方站点发起的,每次请求都会自动发送 Cookie。这就是为什么单独一个 cookie 是不够的,因为每个请求都会包含它。

但是通过在请求本身中也包含令牌,攻击站点无法再生成有效请求,因为它们无法获取用户的令牌。

【讨论】:

【参考方案2】:

好的,让我们将问题分解为原子问题以便更好地理解:

这个 CSRF 是什么?

这是一种网络应用程序漏洞。在最基本的层面上,CSRF 的原因是浏览器不知道如何区分用户是否故意执行操作(例如通过单击表单上的按钮或单击超链接等),或者如果用户在不知不觉中执行了该操作(例如,用户访问了某个域的页面,例如 bad.com,并且当用户已经登录到 good.com 时,bad.com 向 good.com/some_action 发送了请求)。

那么 CSRF 的影响是什么

现在让我们将上面的 good.com 替换为 facebook.com。让我们假设当用户登录到 facebook.com,在他的墙上发表评论时,会发送一个 HTTP GET 请求,格式为 https://facebook.com/postComment?userId=Abhinav_123&comment=HiIAmAbhinav。

现在让我们假设用户在他仍然登录到 facebook.com 时访问了 bad.com 上的一个页面。现在 bad.com 属于攻击者,他在 bad.com 上编写了以下代码:

<img src="https: //facebook.com/postComment?userId=Abhinav_123&comment=I_AM_AN_IDIOT>

现在,只要用户的浏览器在 bad.com 上加载此页面的内容,就会向 facebook.com 发送一个请求:

https://facebook.com/postComment?userId=Abhinav_123&comment=I_AM_AN_IDIOT

因为浏览器会尝试渲染 img 标签。为此,它需要获取 src 中指定的资源,因此它会发送上述 HTTP GET 请求。因此,基本上攻击者实际上可以代表用户向 facebook.com 提交请求,而他实际上并不知道这一点。

现在有什么可能阻止这种攻击?

如果有某种方法可以识别请求是否是由用户故意提出的。因此,为了做到这一点,反 CSRF 令牌出现了。它只是一个随机的、唯一的字符串,由服务器(上面示例中的 facebook.com)生成并发送给用户并在用户的浏览器中设置为 cookie。现在,对于涉及某些敏感操作的每个请求(例如在上面的 facebook 示例中发布评论),浏览器也会将此随机字符串与请求一起发送,并且服务器在执行操作之前将验证随机字符串是否是它所拥有的是否发送到浏览器。

这个想法是攻击者不会知道这个随机字符串。因此,即使攻击者创建了一个如上所示的 img src,并且用户访问 bad.com,也不会执行(在我们上面的示例中发布评论)的操作,因为除了 URL 之外,要执行的操作,还需要一个额外的东西,就是攻击者没有的随机字符串。

但是在 cookie 中再次设置这个随机字符串有一个巨大的缺陷

由于 cookie 的设计方式和浏览器处理 cookie 的方式,在 cookie 中设置这个随机字符串(反 CSRF 令牌)将无法达到我们的目的。根据设计,客户端向服务器发出的每个请求都会自动将 cookie 发送到服务器(简而言之,为简单起见省略了详细信息。有关更多详细信息,请参阅:RFC2965)

因此,在我们上面的示例中,攻击者实际上并不需要知道随机字符串。发布评论操作仍将完成,因为一旦用户访问 bad.com 并加载发布评论 URL(如上所述),随机的反 CSRF 令牌(存在于 cookie 中)将自动伴随请求。

那么解决办法是什么?

服务器 (facebook.com) 需要将其作为隐藏参数放入表单中,并在用户请求发表评论时将此表单(持有 anti-CSRF CSRF 令牌)也应该发布。

现在攻击者无法代表用户执行此敏感操作(除非他以某种方式发现了随机的反 CSRF 令牌本身)

现在来解决登录 CSRF 和双重提交 cookie 的问题

很多时候,网站会通过部署某种形式的 anti_CSRF 令牌架构来保护自己免受 CSRF 攻击。但是很多时候网站并不关心保护他们的登录表单免受 CSRF 攻击。为什么 ? - 因为即使是登录表单也容易受到 CSRF 攻击,并且攻击者试图通过他的域 (bad.com) 向 good.com (facebook.com) 发送登录请求来利用它,用户仍然需要输入他的有效凭据登录 facebook.com。这些凭据仅适用于真正的用户而不是攻击者,因此攻击者无法构建成功的登录请求。

那么这里攻击者的攻击机会是什么?

攻击者可以使用 facebook.com 创建自己的帐户。他现在拥有一套自己的有效凭证。现在,他使用他的登录凭据和他的域 (bad.com) 构建了对 facebook.com 的登录请求。 现在,当用户访问页面 bad.com 时,用户已登录到我的帐户。作为被攻击者,我稍后可以看到用户在帐户上执行的所有活动也可能泄露敏感信息(例如,如果用户选择发送新朋友请求,则发送朋友请求,发送给某人的消息,如果用户这样做,则再次发送登录我的帐户后。所有这些可能性都取决于用户对他已经登录到这个自己的帐户的确信程度,攻击者可以通过使他自己的 Facebook 页面看起来尽可能接近受害者来再次进行处理。他相信这是他的帐户)

那么现在有什么缓解技术呢?

这是我们现在需要的双重提交 cookie。

这是什么意思

双重提交cookie被定义为在cookie和请求参数中发送一个随机值,服务器验证cookie值和请求值是否相等。

它如何帮助减轻攻击?

根据双重cookie的实现原理,当匿名用户(未登录用户)访问登录页面时,服务器会在用户浏览器中设置一个带有一些随机字符串的cookie,并在请求参数中设置相同的好吧(比如说一个表单隐藏字段)。当用户提交登录请求时,这些东西会随请求一起提交 - 用户凭据、隐藏表单字段中的随机字符串和保存随机字符串的 cookie(当然会自动发送)。

现在攻击者可以访问他自己的凭据、服务器在 cookie 中设置的随机字符串以及攻击者的隐藏表单字段。当攻击者将此精心制作的登录请求发送给用户(受害者),并且用户尝试发出此请求时,该用户仍未登录,并且到目前为止是服务器的匿名用户。因此,服务器将在用户浏览器上设置一个具有不同(与攻击者的)随机值的 cookie。现在当用户通过攻击者制作的链接发出登录请求时,该请求将包含攻击者的凭据,隐藏表单字段中的攻击者随机字符串,但 cookie 中的用户随机字符串(来自用户的浏览器)。现在,当这个请求到达服务器时,cookie 中的随机字符串和隐藏的表单字段将不匹配,因此将被标记为异常并进行相应处理。

所以这也是表单返回加密值的原因。希望它清除了这个概念。

【讨论】:

嗨!如果我们有 CORS,我试图理解为什么现在需要这种方法。如果需要,请说明原因!感谢提前 你好@Yuri,如果为什么尽管 CORS 仍然需要反 CSRF 机制,那是你想要问的,让我试一试并尝试解释。就 CORS 中的简单请求而言(无需飞行前),CSRF 仍然是可能的。不那么简单的请求(带有飞行前)实际上取决于 CORS 策略的配置方式。因为,攻击者仍然可以利用 CSRF 漏洞发出飞行前(OPTIONS)请求,然后它取决于服务器在响应中响应的内容。如果服务器过于宽松,攻击仍然会通过。 1) “就 CORS 中的简单请求而言(无需飞行前)CSRF 仍然是可能的” - 你的意思是这里描述的简单请求 developer.mozilla.org/en-US/docs/Web/HTTP/CORS 吗?如果是,则仅旧服务器或正在使用旧代码开发的服务器需要飞行前请求(在***.com/questions/15381105/… 中有解释)。 2)“如果服务器过于宽松”在服务器上正确设置cors设置真的很难吗?

以上是关于csrf 攻击和双重提交的 cookie的主要内容,如果未能解决你的问题,请参考以下文章

Django之CSRF

CSRF Double Submit Cookie 基本上是“不安全的”

csrf攻击

基本 cookie 和 CSRF 问题

初入Csrf Post提交添加管理员

CSRF 和 iframe