目前我正在使用表单发布“评论”并将其保存在数据库中,有两个隐藏字段,一个用于检查评论的组成部分,另一个隐藏字段是评论编号。但我发现了自己形式的漏洞利用。如果我进入开发者控制台,我可以将它们更改为将注释交叉发布到其他表单,或者更改为不存在的内容,这并不重要,也不是我可以更改注释的数量,因为如果有相同数字的评论它仍然可以正常工作。
<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&view=comment&row=2&table=blogs_blogs&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>
答案 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,然后由默认行为处理。