为什么CSRF令牌应该在元标记和cookie中?

时间:2014-01-31 06:05:39

标签: security cookies web csrf meta-tags

有必要使用< meta> 将CSRF令牌名称和值放在< head> 标记中,如:

e.g:

<meta content="authenticity_token" name="csrf-param" />
<meta content="4sWPhTlJAmt1IcyNq1FCyivsAVhHqjiDCKRXOgOQock=" name="csrf-token" />

我已经阅读了关于在CSR中保留CSRF值的概念,但没有找到保留在&lt; head&gt; 标记内的原因。

4 个答案:

答案 0 :(得分:20)

prevent CSRF,您需要一个随恶意网站无法发送的请求一起提交的值。身份验证cookie不适用,因为如果攻击者可以让浏览器向受害者站点发送请求,则会自动提交cookie。

例如,通过www.evil.com上的JavaScript提交表单来攻击www.example.com上的用户会话:

<form method="post" action="https://www.example.com/executeAction">
    <input type="hidden" name="action" value="deleteAllUsers">
</form>

<script>document.forms[0].submit()</script>

在页面中存储反CRSF令牌是OWASP建议的解决方案,用于阻止其他网站提交表单,因为www.evil.com由于www.evil.com无法读取用户会话中的随机令牌{3}}阻止www.example.com上的JavaScript阅读meta的页面内容。

这些令牌可以存储在页面内的任何位置。最常见的是它将在隐藏的表单字段中,但它们也可以存储在Same Origin Policy中。似乎使用{{1}}标签只是另一种存储方式,JavaScript可以在页面提交的任何形式提交中包含它。

答案 1 :(得分:10)

CSRF令牌通常以隐藏表单字段的形式出现。如果您使用JavaScript,将它们放在元标记中才有意义。 JavaScript可以从元标记中读取标记并将它们发布到操作中。

您不希望在Cookie中放置CSRF令牌,因为无论其来源如何,都会针对从Web浏览器向特定网站发出的每个请求发送Cookie。唯一的例外是安全cookie ,它们应该遵循同源策略。

答案 2 :(得分:4)

这是因为没有什么可以阻止违规网站将数据发布到合法网站,其中可能包含您的身份验证票证和CSRF令牌。想象一下这个场景......取自ASP.NET

  1. 用户使用表单身份验证登录www.siteA.com。
  2. 服务器对用户进行身份验证。服务器的响应包括身份验证cookie。
  3. 在不注销的情况下,用户访问恶意网站。此恶意网站包含以下HTML表单:

    <h1>You Are a Winner!</h1>
        <form action="http://siteA.com/api/account" method="post">
            <input type="hidden" name="Transaction" value="withdraw" />
            <input type="hidden" name="Amount" value="1000000" />
     <input type="submit" value="Click Me"/>
        </form>
    
  4. 请注意,表单操作会发布到易受攻击的站点,而不是恶意站点。这是CSRF的“跨站点”部分。

    用户点击提交按钮。浏览器包含带有请求的身份验证cookie。 请求使用用户的身份验证上下文在服务器上运行,并且可以执行允许经过身份验证的用户执行的任何操作。

    基本上,当siteA.com收到CSRF攻击时,它应该将cookie中的CSRF令牌与元标记中的CSRF令牌进行匹配。合法请求将包括两者,但是,伪造攻击将仅包括cookie中指定的CSRF令牌。

答案 3 :(得分:1)

我能想到的唯一选择是使用JavaScript可以访问这些数据。这是因为如果cookie只是http。