验证

时间:2016-04-19 07:53:12

标签: php sql forms security

目前我正在使用表单发布“评论”并将其保存在数据库中,有两个隐藏字段,一个用于检查评论的组成部分,另一个隐藏字段是评论编号。但我发现了自己形式的漏洞利用。如果我进入开发者控制台,我可以将它们更改为将注释交叉发布到其他表单,或者更改为不存在的内容,这并不重要,也不是我可以更改注释的数量,因为如果有相同数字的评论它仍然可以正常工作。

<form action="/index.php?option=com_comments&view=comment&row=<?= $row ?>&table=<?= $table ?>" method="post">
<input type="hidden" name="row" value="<?= $row ?>" />
<input type="hidden" name="table" value="<?= $table ?>" />

<textarea type="text" name="text" class="control control--textarea control-group__control" placeholder="<?= translate('Add new comment here ...') ?>" id="new-comment-text"></textarea>
<br />
<input class="leader btn btn--theme control-row__trigger" type="submit" value="<?= translate('Comment') ?>"/>

但问题是,当我进入控制台并添加然后提交表单时,我实际上可以覆盖该值并发布,因为我是其他人。显然不是那种能够像其他人一样发布的行为。在发送帖子之前,我似乎无法找到验证created_by值的方法,因为如果我将它放在隐藏的输入字段中,它也可以更改。我该怎么做才能确保安全?

编辑:发布是自动完成的,由于我们正在使用的框架,我实际上无法改变它。它会覆盖正确的默认行为。一个更好的方法来表达我的问题是,我可以阻止用户添加额外的隐藏输入字段来发布额外的值吗?如果帖子包含created_by,并且它确实将其更改为当前的profile_id,我是否应该每次发布表单帖子检查?

通过开发者控制台更改了恶意代码

<form action="/index.php?option=com_comments&amp;view=comment&amp;row=2&amp;table=blogs_blogs&amp;created_by=6" method="post" class="ng-pristine ng-valid">
<input type="hidden" name="_token" value="a0b15d3664d7bc0e0e40675095fec014">
<input type="hidden" name="_token" value="a0b15d3664d7bc0e0e40675095fec014">
    <input type="hidden" name="row" value="2">
<input type="hidden" name="created_by" value="6">
    <input type="hidden" name="table" value="blogs_blogs">

    <textarea type="text" name="text" class="control control--textarea control-group__control" placeholder="Add new comment here ..." id="new-comment-text"></textarea>
    <br>
    <input class="leader btn btn--theme control-row__trigger" type="submit" value="Comment">
</form>

3 个答案:

答案 0 :(得分:1)

Web应用程序安全性中的规则#1:永远不要信任客户端

如果用户已登录,请将用户的ID存储在会话中,并仅使用该标识符将他/她的记录存储在数据库中。

另外,您应该在表单中实施一种机制来阻止CSRF(跨站点请求伪造)。因为我无法看到它。

答案 1 :(得分:0)

您可以将会话或cookie与数据库一起使用

[php]

$userHash = $db->prepare('SELECT user_hash FROM user WHERE id = :uId')->scalar([':uId' => $this->getUserId()]);

if (!empty($_SESSION['userHash']) && $_SESSION['userHash'] == $userHash) {
    // process form
    // generate new user hash
} else {
    die('!HACKER!');
}

您可以使用会话ID代替用户ID。

答案 2 :(得分:0)

我通过将此检查添加到实际发布到服务器之前应用的行为来修复它

public function createdbycheck(Library\CommandContext $context)
{
    $context->request->data->created_by = null;
}

只需将其设置为NULL,然后由默认行为处理。