【问题标题】:php secure comment logic?php安全评论逻辑?
【发布时间】:2011-06-01 00:37:12
【问题描述】:

好的,这可能很明显,但还没有点击。我正在创建一个论坛/博客风格的应用程序。

我相当安全地从数据库中获取帖子,但评论开始变得有点困难。 (我可能只是偏执,对吧?)。

如何在不暴露父消息 ID 的情况下添加评论? (例如在隐藏的表单字段或查询字符串中,或​​其他东西)。

我想我有点偏执,有人可能会使用 firebug 或其他东西进入代码,并在提交之前将隐藏的表单字段值更改为其他值。我想我必须确保用户有权评论该特定帖子/类别?

注意事项: 用户已经登录。 不是公开帖子

【问题讨论】:

  • “我想我必须确保用户有权评论该特定帖子/类别?”是的。提交表单后始终检查权限。在客户端-服务器应用程序中,永远不要信任客户端
  • 同意。你没有偏执,你回答了你自己的问题。
  • 哈哈,你可能是对的。只是寻找保护所有类型数据库调用的最佳方法。我很清楚我要做什么。我会很快回来。我感谢 cmets。

标签: php database logic


【解决方案1】:

我建议您像这样设置数据库:

Comments
---------
id
encodedID
authorID
parentID
message

然后,表单字段有两个隐藏值,一个是encodedID,第二个是您创建的哈希值。我建议哈希为:

<?php

$hash = sha1(md5($encodedID . $userID . $_SERVER['REMOTE_ADDR'] . "abc1234"));

?>

然后,当用户提交表单时,验证哈希对于特定的encodedID 和用户是否有效。这是一个简短的代码编写:

<?php

if(isset($_POST['submit']))
{
    //Get the variables and all and sanitize the input of 'message'
    if(sha1(md5($_POST['value1']. $userID . $_SERVER['REMOTE_ADDR'] . "abc1234")) == $_POST['value2'])
    {
        //User is valid.
    }
    else
    {
        //Invalid user.
        //Document this.
    }
}

$value1 = $encodedID; //Grab this from your database
$value2 = sha1(md5($value1 . $userID . $_SERVER['REMOTE_ADDR'] . "abc1234"));
?>

<form method="post" action="comment.php">
<input type="text" name="message" />
<input type="hidden" name="value1" value="<?php echo $value1; ?>" />
<input type="hidden" name="value2" value="<?php echo $value2; ?>" />
<input type="submit" name="submit" value="Comment" />
</form>

编辑:只是一个小提示,但我建议您将 value1 和 value2 更改为抽象的东西,不要将其称为 encodedID 或类似的名称,以免混淆任何用户会尝试破坏它。

是的,md5 和 sha1 并不完全安全,但对于这种情况,它会起作用,因为您希望能够快速有效地处理 cmets。

【讨论】:

  • 用 smaller 输出散列函数的输出是个坏主意。您应该每次都用更多的熵重新散列相同的数据,或者更好的是,只需散列一次。
  • 我喜欢这个。打算尝试几件事。
  • @Jeff Hubbard 类似于:sha1("abc1234567891011" . md5("smaller string"));更安全?现在你提到它是有道理的。
  • sha1(md5()) 闻起来像货物崇拜编程。您显然不信任任何哈希值。是什么让您认为组合两个您不信任的哈希会创建一个更值得信赖的哈希?
  • 不管争论如何,这仍然给了我一个很好的方向。我认为将当前日期(天、小时、秒、毫秒)与用户 ID 之类的内容结合起来有助于创建良好的唯一哈希。
【解决方案2】:

这可能有点矫枉过正,但如果你真的想隐藏当前消息的 post_id,那么你应该考虑使用 session.所以不要在你的表单上使用这样的东西:

<form action="/postcomment.php" method="post" >
   <input name="post_id" type="hidden" value="123" />
   <textarea name="message"></textarea>
</form>

把它简化成这样:

<?php $_SESSION['post_id'] = '123'; ?>

<form action="/postcomment.php" method="post" >
   <textarea name="message"></textarea>
</form>

当然,这是“令人讨厌”的编码,但至少你明白了。

哦,别忘了验证 postcomment.php 上的所有内容。还要转义所有字符串输入值并确保所有数字输入确实是数字(将它们乘以一?)。

[编辑:由于公众的不断要求,请允许我修改上述内容:]

代替:

<?php $_SESSION['post_id'] = '123'; ?>

生成表单id:

<?php $_SESSION['form_id'] = $_SESSION['user_id'].'_'.md5(time()); ?>

然后生成唯一的post_id:

<?php $_SESSION[$_SESSION['form_id'].'_post_id'] = '123'; ?>

提交后获取post_id:

<?php $post_id = $_SESSION[$_SESSION['form_id'].'_post_id']; ?>

【讨论】:

  • 如果发件人在页面中是内联的并且您在 5 个选项卡中打开 5 个帖子怎么办?会话将被最后一个覆盖,如果您先评论,您将收到错误消息。但是,如果表单是在单独的请求中加载的,当然用户没有转到另一个帖子并在那里点击评论回复,这将起作用。所以...这不是论坛/博客编码的正确解决方案。
  • RRStoyanov 是对的。这仅在用户一次只浏览每个帖子时才有用。除非您保留过去 15 分钟内查看的所有帖子的历史记录,否则我认为会话根本无法解决此问题,但仍然很复杂且易受攻击。
  • 正如我在前面所指出的,代码是最简单的形式,以强调使用会话而不是隐藏字段的一般思想;)
  • 我应该提到,一页上有多个帖子,每个帖子都有一个评论部分。不过,我认为朝着一个好的方向前进。
  • @Jhourlad Estrella 但我的意思是,除非你创建一些非常奇怪的抽象系统,但仍然会留下很多漏洞,否则会话根本不会适用于他正在尝试做的事情。
【解决方案3】:

您可以为表单分配一个“id”作为隐藏字段并创建一个数据库表来跟踪表单 id 及其相关的帖子 id,这样当表单被提交时,您可以在数据库中检查帖子 id 而无需发送根据随帖子返回的表单 ID 将其发送给客户端

【讨论】:

    【解决方案4】:

    您在这里问了一个错误的问题:与其担心用户获得一些在您的应用程序之外没有任何意义的内部 ID,您的主要关注点应该是防止他们做任何不愉快的事情它。

    想象一下,我刚刚开始发送 POST 请求,为 1 到 10,000 之间的每个 ID 添加评论。我肯定迟早会打出真正的帖子。

    关于编写安全 Web 应用程序的规则 #1:不要信任用户。

    换句话说,是的,当您从发件人那里收到结果时,您应该检查以确保他们有权发表评论。

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 2023-03-28
      • 2012-06-28
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 2014-09-04
      • 1970-01-01
      • 2010-12-09
      相关资源
      最近更新 更多