可以使用(加密强)会话 cookie 作为 CSRF 令牌吗?

Posted

技术标签:

【中文标题】可以使用(加密强)会话 cookie 作为 CSRF 令牌吗?【英文标题】:Is it ok to use the (cryptographically strong) session cookie as CSRF token? 【发布时间】:2012-05-27 22:37:35 【问题描述】:

阅读OWASP CSRF prevention cheat sheet,提出的防止此类攻击的方法之一是同步器令牌模式。

如果会话令牌在密码学上很强大,它是否可以像下面的伪代码中描述的那样兼作 csrf 令牌?

客户:

<script>
dom.replace(placeholder, getCookie("session-cookie"))
</script>

<form>
<input type="hidden" name="csrf-cookie" value="placeholder-value"/>
<input type="text" />
</form>

服务器:

if(request.getParameter("csrf-cookie") != user.getSessionCookie())
    print "get out you evil hacker"

cookie 在页面加载时使用 javascript 设置,以防止用户意外泄露会话 cookie,例如:将页面副本通过电子邮件发送给朋友。

【问题讨论】:

致整个页面:使用会话令牌作为 CSRF 令牌 will work 但暂时是 advised against by OWASP,因为存在攻击者可以通过以下方式获取用户的 CSRF 令牌的现实情况不允许允许他们直接获取会话令牌的漏洞。这种情况无论如何都是一件坏事——但如果你将会话令牌作为 CSRF 令牌重用,那么会话令牌当然也会受到损害,这更糟。 【参考方案1】:

,您不应将会话令牌重复用作您的 CSRF 令牌。 OWASP CSRF 预防备忘单给出了为什么不希望使用会话标识符作为 CSRF 令牌的原因:

虽然这种方法可以有效降低跨站点请求伪造的风险,但在 HTTP 参数中包含经过身份验证的会话标识符可能会增加会话劫持的总体风险。架构师和开发人员必须确保没有网络设备或自定义应用程序代码或模块显式记录或以其他方式披露 HTTP POST 参数。

跨站点脚本攻击也可以利用在 html 中包含会话标识符来绕过 HTTPOnly 保护。大多数现代浏览器会阻止客户端脚本访问 HTTPOnly cookie。但是,如果将 HTTPOnly 会话标识符放在 HTML 中,则会失去这种保护,因为客户端脚本可以轻松遍历并从 DOM 中提取标识符。仍然鼓励开发人员实现本文所述的同步器令牌模式。

Here 是关于为什么使用会话 ID 作为 CSRF 令牌可能不是一个好主意的一些想法。 This article 提到对普通 http 连接进行数据包嗅探以及对它们进行中间人攻击的能力是潜在风险。

因此,CSRF 令牌必须是一个不同的令牌,否则如果我们假设攻击者已经知道会话标识符,那么 CSRF 令牌将很容易被猜到!更加防御性地说:玩火可能不是一个好主意:没有必要重新使用会话 ID 作为 CSRF 令牌,这样做只会打开另一个可能被利用的攻击面。无需重复使用,无需担心。

因此,尽管会话令牌在密码学上是安全的,但它还应该独立于 CSRF 令牌(也在概率意义上),以便整个事物在上述假设下工作。这也是为什么任何实现示例总是从头开始创建其令牌的原因。

您可以使用加密安全的随机数生成器来创建字节序列,对它们进行十六进制或 Base64 编码以获得要嵌入页面的字符串。 OWASP 建议长度为 128 位,其中假设 64 位熵(例如,将 8 个随机字节转换为 16 字节十六进制字符串)。该序列的长度决定了安全级别:猜测一个 10 字节的安全随机数(具有 80 位熵)以 2^(-80) 的概率成功,这在大多数应用程序中应该足够了。所以你的最终令牌应该有 20 字节的长度,一个 10 字节的随机数转换为十六进制编码。

【讨论】:

【参考方案2】:

任何无法被外部站点检索到的东西都可以用作 CSRF 令牌。所以会话 cookie 的内容就可以了。

【讨论】:

这也是我们所怀疑的,但我想确定一下,因为我可以挖掘的所有示例都为此目的创建了一个新令牌。 OP 的解决方案只有在会话 ID 没有设置 httpOnly 时才有效,不推荐这样做。 我更喜欢“会起作用”这个词而不是“很好”,因为这里的另一个答案中描述了 个反对这种做法的有效论据。 但是仅仅检查会话是否以某种方式发送是不够的。仅当会话 cookie 在 url 中时,CSRF 保护才存在 - 对吗?

以上是关于可以使用(加密强)会话 cookie 作为 CSRF 令牌吗?的主要内容,如果未能解决你的问题,请参考以下文章

登录页面使用 SSL,未加密页面看不到加密会话 cookie (Grails, Acegi)

加密会话(SSL)Cookie 中缺少 Secure 属性 漏洞修复

用 Java 解决“加密会话 (ssl) cookie 中缺少安全属性”

IBM AppScan - 加密会话 (SSL) Cookie 中缺少安全属性

加密会话(SSL) Cookie 中缺少中Secure属性

带有加密cookies的PHP会话类