这是跨站点形式注入的安全解决方案吗?

时间:2016-09-13 21:29:13

标签: php forms security

想象一下,我们有一个像这样的表格

<?php
session_start();
$_SESSION['token'] = rand(0, 6000000);
echo '
<form method="post" action="submit.php/?token='.$_SESSION['token'].'">
...
</form>
';
?>

表单处理程序submit.php

<?php
if($_GET['token'] == $_SESSION['token']) {
//form is valid, do stuff
} else {
header("Location: index.php");
//give the attacker boot
}
?>

是否可以通过在第三方网站上向http://somesite.com/submit.php?token=non-genuine-number运行表单提交请求来伪造此表单?我们不是在讨论欺骗管理员点击正版网站上的链接中间版本,当生成令牌的$_SESSION数据时可能会被欺骗但是没有正确会话数据的人。

1 个答案:

答案 0 :(得分:0)

从安全角度来看,它不会被视为安全。

攻击者可以假设(甚至观察)用户何时下载表单,并在合适的时间发起攻击。他还需要命中从6000000中选择的数字,熵似乎是~22.5位,已经太少了,但实际上它甚至更少,因为rand()不是加密安全的(而不是random_bytes()或random_int(或者从Linux上的/ dev / urandom读取。)

因此,虽然实际利用它可能并不简单,但任何安全代码审查都会发现它是一个缺陷,因为它违背了最佳实践。

修改

你可以通过做两件简单的事情来改进解决方案(有效地正确实现同步器令牌模式):

  • 使用像random_bytes()

  • 这样的安全prng
  • 大量增加熵

如果您生成了像bin2hex(random_bytes(16))这样的令牌,那就更好了。

编辑2:

挑剔的另一件事。最好不要在URL中发送令牌,因为URL参数将记录在所有类型的地方,攻击者可能从中获取它。但是,如果它是一次性令牌(每个页面请求生成一个新令牌),则可以稍微降低风险。使用OWASP和其他人建议的隐藏表单字段仍然会更好。