很好地理解CSRF的棘手问题

时间:2011-02-18 19:39:03

标签: security xss

我和我的朋友喝啤酒。

来自维基百科:

  

需要一个特定于用户的秘密   所有形式提交的令牌和   副作用URL阻止CSRF;该   攻击者的网站无法把权利   提交中的令牌

atacker可以间接使用浏览器cookie,但他不能直接使用它们! 这就是为什么他不能使用document.write()

将cookie放入链接

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

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

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:4)

这种先发制人的安全系统对CSRF免疫。这样做的原因是因为在CSRF攻击中,浏览器会跟踪cookie,因此攻击者在构建请求时不需要知道cookie值。如果这个提议的安全系统容易受到CSRF的攻击,那么像下面的概念验证一样会出现浏览器:

<img src=http://victim_site/index.php?action=logout&sid= />

显然,在这种情况下,sid需要一个值,攻击者无法在不使用XSS的情况下获得此值,这使得这个问题没有实际意义。使用xss,攻击者可以读取CSRF令牌以伪造请求。这用于MySpace worm Sammy

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

答案 2 :(得分:2)

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

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

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

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

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

另请参阅:CSRF Validation Token: session id safe?

答案 3 :(得分:-4)

是什么阻止某人编辑你发送给他们的HTML,以及你发送给他们的cookie?两者都在用户的控制之下。

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

现在,如果你修改了你的版本以便SERVER存储该ID,那么攻击就更难了......

$_SESSION['form_token'] = 's33krit valu3';

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

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


你欠你的朋友一杯啤酒。