PHP对反CSRF令牌的进一步安全性

时间:2012-11-11 10:41:13

标签: php csrf

我正在学习如何使用反CSRF令牌来防止CSRF。基本上,这个想法是: -

1)生成一个令牌,例如Md5或Sha1,然后将此值存储在会话变量中: -

$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;

2)所有表单都在POST隐藏字段中包含此标记值

<input type='hidden' name='token' value='$nonce_token' />

例如,在源代码中用户的样子: -

<input type='hidden' name='token' value='9ee66e4e63a06ee4b83a3edde4ecd587' />

3)表格发送后,检查POST隐藏字段标记值与存储在会话值

中的标记匹配
if($_POST['token']==$_SESSION['token']){...ok...}

但是,这个过程似乎有点瑕疵,因为通过在隐藏的POST字段中包含令牌值,攻击只需查看网站源代码即可查看令牌,然后将其包含在恶意生成的POST表单中。因此,当收到的令牌值匹配我的会话变量中的令牌值时,应用程序将成功收到,因为我基本上在隐藏字段中向攻击者显示令牌值。

因此,我的问题是围绕这个问题的最佳方法是什么,因为我仍然认为一些想法似乎没有什么缺陷: -

1)使用_GET代替,但这仍然有像_POST

这样的缺陷

2)在x分钟或每个请求之后更改令牌值,但在浏览器中返回时会导致可用性问题,或者当用户填写表单和令牌值与更新的会话令牌值相比过时会失败,因为隐藏令牌值不会用户填写表格时更新。

3)尝试加密隐藏的POST表单令牌值,然后在发送POST时解密,但加密/解密已经散列的值似乎很复杂,特别是加密的一种方式具有MD5等值?

非常感谢任何想法。

4 个答案:

答案 0 :(得分:3)

您需要做的是使用salt将隐藏字段设置为会话ID的MD5或SHA1哈希。这样,您可以将提交的值与会话ID加上salt的哈希进行比较,如果匹配则有效。如果攻击者可以猜出令牌,那么他们已经窃取了会话ID,并且由于登录已被劫持,因此无需再进行保护。它真的很简单。以下是每个OWASP关于如何防止CSRF的一些重要信息https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

答案 1 :(得分:2)

  

然而,这个过程似乎有点瑕疵,因为通过在隐藏的POST字段中包含令牌值,攻击只需查看网站源代码

不,他们不能。

Alice经营一个网站。鲍勃访问该网站。马洛里正在攻击鲍勃的账户。

鲍勃在访问爱丽丝的网站时获得了一个随机令牌。

如果Mallory访问该网站,Mallory会得到一个不同的 nonce(因为Mallory会有不同的会话)。

如果Mallory在其中生成了包含恶意数据的表单(在她的网站上)并欺骗Bob提交,那么表单中提供的nonce Mallory将与Bob的会话中的nonce不匹配,并且提交将被拒绝。

答案 2 :(得分:2)

让我们回顾一下攻击情景:

  1. 您的服务器位于example.com,并且您在表单中使用了CSRF令牌。
  2. 每个CSRF令牌都是唯一的,特定于用户且仅在一段时间内有效。
  3. 恶意的第三方,Eve,欺骗你的一个用户Alice,来到她的网站,试图发起CSRF攻击。
  4. 如果Eve只是欺骗Alice在没有CSRF令牌的情况下向您的服务器提交表单,那么您的服务器将拒绝它。
  5. 如果Eve在您的服务器上也有一个帐户并尝试使用该表单提交任何令牌,则会失败,因为该令牌对Alice无效。
  6. 这留下了这种情况:使用Javascript,Eve从您的服务器中取出一个表单作为Alice ,然后提交此表单,包括一个有效的令牌。即Eve完全模仿Alice使用Javascript进行常规表单提交的整个过程。这是Same Origin Policy阻止的。 Eve的Javascript将无法从您的服务器获取信息,Alice的浏览器将阻止此操作,因为它违反了同源策略。

    也就是说,假设浏览器中没有允许Eve绕过该策略的安全漏洞。这也意味着您需要防范XSS,即夏娃能够将她的一个脚本注入您的网站,因此您网站的常规访问者将从同一个来源运行Eve的脚本作为您网站的一部分。


    作为一点自我推销,我刚刚实现了一个基于签名的CSRF令牌库,您可能需要查看它:Kunststube\CSRFP。我也喜欢征求同行评论和批评,而我正在接受它。

答案 3 :(得分:1)

首先,你必须记住,你不能阻止黑客攻击你的应用程序,只有你可以让事情变得更难。

当您考虑CSRF攻击的主要目标时,这个想法就变得清晰了,CSRF是一种攻击,它会诱使受害者加载包含恶意请求的页面。它是恶意的,它继承了受害者的身份和特权,代表受害者执行不受欢迎的功能,例如更改受害者的电子邮件地址,家庭住址或密码,或购买某些东西。 CSRF攻击通常针对导致服务器状态更改的功能,但也可用于访问敏感数据。

如上所述,攻击者不会直接攻击您的网页,他们需要桥接,即他们需要受害者,因此他们可以使用受害者身份和权限来执行操作。

当你说:

  

然而,由于将令牌值包含在a中,这个过程似乎有点瑕疵   隐藏的POST字段攻击只需查看网站源代码

即可

它没有意义,因为攻击者不会攻击自己。

我希望这是充分的帮助。