形式欺骗和解决方法

时间:2012-06-26 23:42:05

标签: php html forms security

我正在尝试开发一个表单助手来防止表单欺骗。所以我想出了这个:

<form...>
<?=form::secure()?>
...
</form>

使用密钥'_token'标记隐藏的表单,该标记是用户会话ID的md5(随机并在1周后续订)。 然后在“动作”网址(来自表格):

$token = (isset($_GET['_token'])) ? $_GET['_token'] : null;
$token = (is_null($token) and isset($_POST['_token'])) ? $_POST['_token'] : $token;
if (form::is_secure($token)) { // checks if the given token is equal to md5(user id)
    ...ok...
} else {
    ...error...
}

这是否可以防止形式欺骗或我遗漏了什么?如果用户ID在用户刚加载页面然后提交表单的确切时刻到期,则只会打印错误,他应该再次提交表单,但这是可以接受的(很少见)。

我认为唯一可能出错的是,如果潜在的攻击者能够获得用户会话ID,那么他可以将?_token = id附加到它的请求并将其提供给用户进行浏览,但是那一点,如果攻击者拥有用户会话ID,它无论如何都可以做任何他想做的事情。

我是对的吗?如果没有,我如何编辑我的代码以实现我的目标?

2 个答案:

答案 0 :(得分:5)

您正在有效地重新发明轮子,因为令牌需要有效的会话来验证,因此只重复会话的安全层而不添加任何额外的内容。这相当于要求某人输入密码,然后再次要求确认。它可能会让每个人都感觉更好,但如果密码被泄露,它只会减慢攻击速度但不会阻止它。

这并不是说你不应该认真对待这些事情或拒绝你的尝试。我的理念是,表单的内容(通过GETPOST传递的内容)应该与其他逻辑分开,例如安全性和计算,并且服务器不应该考虑用户 - 提供的数据不是用户提供的数据。理想情况下,任何人都可以向表单操作发布任何内容,服务器/控制器将正确且一致地管理它。验证会话(安全性),清理数据然后验证数据,并重新计算/验证用户实际使用Web表单时通过JS生成的任何值。理想情况下,响应是通用的,可以是重定向或Web标准响应,因此请求者(无论是Web浏览器,命令行用户还是Web服务)都可以解释它。

如果出现以上情况,那么欺骗的重点和关注就会减少,更多地强调分别增强安全层和验证层,最重要的是,做得好的后端控制器可以轻松移植/作为Web服务后端重用。

长话短说:您的解决方案并不坏,就我所知,它只是没有添加任何真正的安全性,甚至可能暴露您的后端安全逻辑。如果您有特定的欺骗问题/威胁,最好解决该用例并解决问题,而不是试图立即提出一个适合所有人的解决方案。可能会发现您的用例具有需要在交换的不同点解决的特定解决方案/注意事项。

答案 1 :(得分:1)

不要重新发明轮子。如果您没有使用Web框架,请集成一个为项目添加CSRF保护的无数库,例如CSRF4PHP

您的解决方案已关闭,但无法正常运行,因为会话ID可能会被攻击者废弃。