在Rails中为经过身份验证的POST端点禁用CSRF保护是否安全?

Chr*_*ang 2 security iframe ruby-on-rails csrf

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

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

我是否会通过禁用该特定端点的CSRF保护来打开自己的任何其他安全风险,还是可以安全地依赖身份验证before_filter来阻止CSRF令牌防范的恶意请求?


下面是一个更详细的解释,为什么我想这样做,如果有人感兴趣.

我的用例是我基本上想要创建一些非常类似于Facebook的按钮,但是这个按钮(与Facebook版本不同)通常会在同一页面上多次出现.

CSRF保护工作正常,但用户使用空cookie访问页面的情况除外.

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

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

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

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

当然,最好避免弹出窗口中闪烁的符号,因此我想一起禁用CSRF保护以便进行create操作.

Fre*_*ung 10

经过身份验证的请求正是CSRF的目的.

CSRF的含义是攻击者说服用户的浏览器发出请求.例如,您访问由攻击者托管的页面,其形式看起来像

<form action="http://www.yourapp.com/some_action">
  #for parameters here
</action>
Run Code Online (Sandbox Code Playgroud)

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

对于未经身份验证的请求,csrf没有任何意义 - 攻击者可以继续执行请求 - 他们不需要劫持受害者的​​凭据.

所以,短版本:禁用csrf保护会让你容易受到csrf风格的攻击.

CSRF的真正含义是确保表单包含攻击者无法伪造的参数.会议是一个容易存储这样一个价值的地方,但我想你可以提出替代方案.例如,如果用户无法控制表单中的任何参数,则可以添加另一个参数,该参数将是表单中所有其他参数的签名(可能具有某种时间戳或nonce以防止重放攻击).收到请求后,您可以通过验证签名来判断请求是否来自您生成的表单.

对这类东西要非常小心,因为它容易出错(即使是大男孩有时也会弄错).