2

我发现自己处于一种情况,如果我可以在我的 rails 应用程序中禁用 CSRF 令牌检查端点,我可以提供更好的用户体验。

端点是一个create动作(由 路由到POST /whatever),位于设计:authenticate!过滤器后面。

我是否会通过禁用该特定端点的 CSRF 保护来使自己面临任何额外的安全风险,或者我是否可以安全地依赖身份验证before_filter来阻止 CSRF 令牌所保护的恶意请求类型?


如果有人感兴趣,以下是关于我为什么要这样做的更详细的解释。

我的用例是,我基本上想创建与 Facebook 的点赞按钮非常相似的东西,但是这个按钮(与 Facebook 的对应按钮不同)通常会在同一页面上出现多次。

CSRF 保护工作正常,除了用户访问带有空 cookie 的页面的情况。

在这种情况下,rails 会为 X 个请求中的每一个生成一个新会话,因为它们都是无 cookie 的。当然,对于每个新会话,都会生成一个新的 CSRF 令牌并在对 iframe 的响应中返回。

由于浏览器只为域保留一个 cookie,因此来自每个 iframe 的任何后续请求都将映射到同一会话,因此所有 CSRF 令牌(除了一个)都是无效的。

映射到单个会话很好,因为可以提示用户登录一次,然后在每次按下后续按钮时映射到相同的登录 - 无需重新加载页面。

折衷方案是用 响应401 Unauthorized,但保留被拒绝请求的会话(通过覆盖handle_unverified_request)。这将再次触发登录弹出窗口,但这一次会发生即时重定向,因为用户已经登录。

当然,最好避免登录弹出窗口的闪烁,因此我想一起禁用 CSRF 保护只是为了create操作。

4

1 回答 1

10

经过身份验证的请求正是 CSRF 的意义所在。

CSRF 的意思是攻击者说服用户的浏览器发出请求。例如,您访问了一个由攻击者托管的页面,该页面的表单看起来像

<form action="http://www.yourapp.com/some_action">
  #for parameters here
</action>

以及自动提交表单的页面上的一些 javascript。如果用户已经登录到您的应用程序,则此请求将通过任何基于 cookie 的身份验证检查。然而,攻击者不知道 csrf 令牌。

对于未经身份验证的请求,csrf 没有任何作用——攻击者可以继续发出请求——他们不需要劫持受害者的​​凭据。

所以,简短的版本:禁用 csrf 保护将使您容易受到 csrf 风格的攻击。

CSRF 的真正目的是确保表单包含攻击者无法伪造的参数。会话是存储此类值的简单场所,但我想您可以提出替代方案。例如,如果用户无法控制表单中的任何参数,您可以添加另一个参数,该参数将作为表单中所有其他参数的签名(可能带有某种时间戳或随机数以防止重放攻击)。收到请求后,您可以通过验证签名来判断请求是否来自您生成的表单。

对这类事情要非常小心,因为很容易出错(甚至大男孩有时也会出错。

于 2012-05-18T12:49:07.273 回答