【问题标题】:Tricky question for good understanding of CSRF很好理解 CSRF 的棘手问题
【发布时间】:2011-02-20 00:51:57
【问题描述】:

我的朋友和我有一个标准啤酒。

来自维基百科:

需要用户特定的秘密 所有表单提交中的令牌和 副作用 URL 阻止 CSRF;这 攻击者的站点无法正确放置 提交中的令牌

攻击者可以间接使用浏览器cookie,但不能直接使用! 这就是为什么他不能使用document.write()将cookies放入链接中

让我们看看注销链接是如何生成的。这是安全的方式吗?这个 GET 请求可以伪造吗?

function logout(){
     echo '<a href="?action=logout&sid='.htmlspecialchars($_COOKIE['sid']).'>Logout</a>';
}

sid 是会话 ID,为每个会话生成

在服务器端,执行以下检查:

$_GET['sid']==$_COOKIE['sid']

【问题讨论】:

    标签: security xss


    【解决方案1】:

    绝对不是!切勿将会话标识符用于 CSRF 保护。

    至于为什么?嗯,答案很简单。这样做为session hijacking 攻击打开了大门。想象一下,有人出于某种原因将链接复制并粘贴到电子邮件或网络上。现在,电子邮件另一端的人拥有该会话的会话标识符。当然,如果他们点击链接,它不会激活会话,但是知道他们在做什么的人仍然可以使用它。

    也不要使用秘密 cookie。每次请求都会传输 Cookie。因此,仅存在 cookie 并不能验证用户是否打算发出请求。

    该怎么做呢?关注OWASP recommendations。使用在每个请求上发布并与会话相关联的唯一随机令牌。然后验证令牌在提交时是否有效,然后使令牌无效!它应该只是一次性使用的令牌。通过表单提交,而不是直接附加到链接...

    【讨论】:

    • @Rook:哪一部分不正确?我从来没有说过它打开了 CSRF 攻击。只是在 url/for csrf 中使用会话标识符可以打开其他攻击向量。我提供了最好的替代方案,即使用一次性令牌。那么有什么不完全正确的呢?
    • 我认为这并不能完全解决手头的问题。只是一个小小的分歧,我不会反对你或任何事情。如果您想了解我对该主题的立场,欢迎您阅读我的回答。
    • @Rook:我只是好奇你认为什么是不正确的。如果它没有完全解决问题,那很好。我只是好奇我是否可以改进它(并提高我的知识)。除非我遗漏了什么,否则我们的答案是免费的……
    • 啊,对。在我的帖子中,我没有考虑复制+粘贴链接的可能性。
    • @ircmaxell 哦,完全。我想我的意思是它可以导致会话劫持,但我看到的唯一情况是如果您使用的是http_only cookie然后您有一个xss向量。此外,OP 希望更深入地了解 CSRF,重要的是要注意这在技术上不受 CSRF 影响。
    【解决方案2】:

    这个经过验证的安全系统不受 CSRF 影响。之所以可行,是因为在 CSRF 攻击中,浏览器会跟踪 cookie,因此攻击者在构建请求时不需要知道 cookie 的值。如果这个提议的安全系统容易受到 CSRF 的攻击,那么像下面的概念证明这样的漏洞会注销浏览器:

    &lt;img src=http://victim_site/index.php?action=logout&amp;sid= /&gt;

    显然,在这种情况下 sid 需要一个值,而攻击者不使用 XSS 就无法获得该值,这使得这成为一个争论点。使用 xss 攻击者可以读取 CSRF 令牌来伪造请求。这是在MySpace worm Sammy 中使用的。

    使用 cookie 是一种有效但较弱的 CSRF 保护形式。一个问题是它完全破坏了http_only cookies。理想情况下,CSRF 令牌和会话 ID 应该是 Cryptographic nonce。但是,让它们成为单独的值更安全。

    【讨论】:

      【解决方案3】:

      编辑:这个答案至少部分错误。使用会话 ID 作为 CSRF 令牌可能导致会话劫持,例如,如果链接被复制+粘贴。请参阅 ircmaxell 的答案和 cmets。

      是的,因为会话 ID 是随机的并且与用户相关联,所以它是一种可接受的 CSRF 保护形式。

      也就是说,如果恶意 JavaScript 能够获取会话 cookie(和会话 ID),那么使用不同的随机数会更安全......但如果我不得不在“无 CSRF 令牌”和“会话 ID 作为 CSRF 令牌”之间进行选择,我总是选择会话作为 CSRF 令牌。

      使用会话 ID 作为 CSRF 令牌的唯一潜在问题是:如果有人能够窃取 CSRF 令牌,他们也将能够劫持相关的会话......但我想不出一个明智的场景成为一个问题。

      现在,从下面关于 Marc B 的回答的讨论中:使用nonce 将提供其他好处(例如防止重复提交表单)......但它对 CSRF 攻击不再安全比会话 ID(我在第一段第二段中提到的一个警告)。

      另见:CSRF Validation Token: session id safe?

      【讨论】:

      • 我肯定会使用其他一些随机令牌来代替 SID。问题是针对大脑训练提出的)
      • 上面给出的方法的优点是您不必为每个用户生成额外的唯一令牌并将它们存储在数据库中。这是让应用更简单的方法
      • 是的,当我说“如果我必须选择……”时,我就是这么想的。完全唯一的令牌会更好一些,但会话 ID 不会造成任何安全问题(我可以看到),而且它们总比没有好。
      • 会话 ID 不是请求身份验证令牌!两者的目的完全不同。
      • @David:我不会反对这个答案。里面有很好的信息。唯一的问题在于边缘情况。所以这不是(我+1ed)...
      【解决方案4】:

      如何阻止某人编辑您发送给他们的 HTML 以及您也发送给他们的 cookie?两者都在用户的控制之下。

      使用 firebug,我可以轻松更改任何页面的内容以及任何 cookie。

      现在,如果您修改了您的版本,以便 SERVER 存储该 ID,那么破解将更加困难......

      $_SESSION['form_token'] = 's33krit valu3';
      
      if ($_POST['form_token'] == $_SESSION['form_token']) {
        ... everything's ok ...
      }
      

      由于会话数据保存在服务器上,不受攻击者的控制,这比相信攻击者不会想到修改 cookie 要安全得多。


      你欠你朋友一杯啤酒。

      【讨论】:

      • 除非我有误解,否则这不是他试图防御的攻击媒介。他试图确保 evil.com 不会执行 CSRF 攻击(例如,通过使用 &lt;img src="happy.com/logout.php" /&gt;)。
      • 此外,您的“s33krit valu3”需要发送到客户端(例如,用作 GET 参数或隐藏的表单元素),所以我'我不知道它如何更安全。
      • @Marc B:我相信 Dan 担心跨站点请求伪造,即。有人给你一个链接dan's-server.com/?action=logout 并让服务器将你注销(或其他一些操作)。当服务器在 cookie 和 URL 中都需要正确的会话 ID 时,如果不知道您的会话 ID,就不可能给您这样的链接。
      • @Marc:nonce 确实有价值,可以用作 CSRF 保护……但它提供的 CSRF 保护并不比会话 ID 提供的更多。
      • 在发布有关 CSRF 之前,请阅读整个 Browser Security Handbook
      猜你喜欢
      • 2011-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多