【发布时间】:2021-08-15 20:03:56
【问题描述】:
我有一个网站,允许用户提交 POST 请求以执行操作,并通过标准 PHP 会话 cookie 进行身份验证。举个极端的例子:
<!-- real site !-->
<form action="http://victimserver.com/accountactions.php">
<input type=hidden name="request" value="delete_all_my_account_data">
This button will delete all your account data! Please be sure you mean it!
<input type="submit" name="delete" value="Delete All">
</form>
我理解 CSRF 令牌的原因是为了防止另一个站点上的表单将我自己的站点设置为目标并模仿我站点的命令,导致受害者的浏览器忠实地代表他们提交 cookie,并成功执行命令:
<!-- attacker site !-->
<form action="http://victimserver.com/accountactions.php">
<input type=hidden name="request" value="delete_all_my_account_data">
Click this button if you love chocolate cake!
<input type="submit" name="delete" value="Yes, I love chocolate cake!">
</form>
显然,我不想让我的网站如此容易成为目标。作为最简单的缓解方法,我将 PHP_SESSID cookie 直接注入到表单中,并在服务器端进行比较:
<!-- real site, improved !-->
<form action="http://victimserver.com/accountactions.php">
<input type=hidden name="request" value="delete_all_my_account_data">
<input type=hidden name="csrf" value="abcdef45678zyxwvu01234">
This button will delete all your account data! Please be sure you mean it!
<input type="submit" name="delete" value="Delete All">
</form>
这似乎涵盖了所有基础。在 CSRF 攻击中,会话 cookie 无论如何都应该不为攻击者所知(游戏已经结束),因此他们无法轻易模仿其网站上的隐藏参数。
除了碰巧是最简单的缓解方法之外,您能否告诉我上述方法是否存在真正的问题?
【问题讨论】:
-
如果以GET形式注入session id,则表示该id会出现在URL中。强烈建议避免这种情况。
-
JS 也将能够读取 id。 JS 不应访问会话 ID。
-
Olivier,我在我的网站上使用 method=post 但在示例中忘记了。客户端仍然必须以某种方式知道 CSRF 令牌才能提交它,不是吗,无论是在脚本还是 html 中?有第二个包含随机数的 cookie 可以吗?
标签: php html security cookies csrf