如何让$ _GET更安全。

时间:2010-09-10 05:42:13

标签: php get security

我正在使用get方法执行某些操作,例如,批准,markasspam,delete,用于评论系统。我知道走这条路是非常不安全但我无法帮助它。因为使用$ _GET方法的原因是使用PHP_SELF在页面本身内执行操作,而FYI我也使用post方法使用复选框来执行操作。

现在为了使它有点安全我想随机化数字或生成哈希或其他东西,然后比较它,获取id并执行操作

我目前的代码有点像这样。

<?php 
if($approve == 1 ) 
{ 
    ?>
    <a href="<?php echo $_SERVER['PHP_SELF']."?approve=".$id; ?>">Unapprove</a>
    <?php 
} else 
{ 
    ?> 
    <a href="<?php echo $_SERVER['PHP_SELF']."?unapprove=".$id; ?>">Approve</a>
    <?php 
}
?> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?spam=".$id; ?>">Spam</a> 
| <a class="edit-comments" href="edit-comments.php?id=<?php echo $id; ?>">Edit</a> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?delete=".$id; ?>">Delete</a>

我使用此代码执行操作..

if(isset($_GET['approve'])) {
    $id = intval($_GET['approve']);
    $query = "UPDATE comments SET approve = '0' WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['unapprove'])) {
    $id = intval($_GET['unapprove']);
    $query = "UPDATE comments SET approve = '1' WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['delete'])) {
    $id = intval($_GET['delete']);
    $query = "DELETE FROM comments WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['spam'])) {
    $id = intval($_GET['spam']);
    $query = "UPDATE comments SET spam = '1' WHERE id = '$id'";
    $result = mysql_query($query);
}

而不是使用批准或取消批准或删除或垃圾邮件,我想随机化或散列这些单词并希望它尽可能冗长,然后执行操作。

我该怎么办?你对此有何看法?

  

编辑:请注意只有   经过身份验证的用户即管理员   能够执行此操作。甚至   虽然它通过身份验证   系统我想增加更多的安全性   即使是管理员。避免实验   或意外

代码不准确只是让你理解我想要实现的样本。

3 个答案:

答案 0 :(得分:5)

此处是否使用GET或POST参数在此上下文中并不重要 - 脚本首先需要 的是某种身份验证。 (完成之后,您可以进入安全性详细信息,其中GET的安全性略低于POST - 请参阅注释以获取详细信息。)

我说你有两个选择:

  • 使用.htaccess保护整个脚本 - 脚本本身无需更改

  • 介绍PHP边用户身份验证,并仅在登录用户发出请求时执行操作。需要对脚本进行根本性更改,但最灵活。

重新编辑:

事实证明您的脚本已受到保护。在这种情况下,我假设您对URL中出现的增量ID号,在浏览器中缓存等等感到不舒服。通常的解决方案是为每个注释创建一个随机密钥(除了增量ID)。该密钥存储在一个单独的列中(不要忘记添加索引),并且您将与之匹配。

更进一步的步骤是为每个动作创建临时哈希,这是对一些外部攻击的最终保护。

关于使用一次性哈希的修改:

我从来没有在管理界面中实现一次性哈希,所以我没有这方面的经验,但我想一个非常简单的实现会将动作哈希存储在一个单独的表中,列hashrecordaction。每当您的工具列出许多记录并输出“删除/批准/取消批准”链接时,它将在哈希表中为每个注释生成三条记录:一条用于删除,一条用于批准,一条用于未批准。然后,“删除/批准/取消批准”链接将获取正确的散列作为唯一参数,而不是记录ID和命令。

为未使用的哈希添加超时功能(加上删除实际使用的任何哈希值),然后就完成了。

答案 1 :(得分:1)

你可以这样做,$_GET不是代码中不安全的东西。不安全来自于您没有检查用户是否是例如授权删除评论。

在您当前的代码中,任何人都可以随时随地删除任何内容。

如果你有一个包装代码,确保enter good reason here没有执行你的if语句,那就没关系。

但你应该尝试验证,参数的内容实际上是整数,而不仅仅是int_val'ing它们并直接在数据库中使用它们。

在您的修改

你应该检查你的参数是否真的是一个int。 intval("test")也会返回一个整数,大多为0。

您可以考虑使用正则表达式来验证字符串只包含数字:preg_match('/[0-9]+/', $_GET['id']);

如果是,您可以执行操作。

答案 2 :(得分:0)

您不应将GET用于任何更改服务器上数据的操作。决不。您只能使用它来获取数据。

如果您不能使用表单作为操作按钮(因为它们之外还有其他表单),您应该考虑这个设计:

  • 您使用AJAX对服务器执行POST请求
  • 在禁用javascript的环境中,您使用GET链接,例如user.php?action = delete,它会在单独的页面上显示非常简单的表单。表单中的标题询问:“您确定要删除用户X吗?”它有两个按钮:1)“是” - 向操作脚本提交POST请求,2)“否” - 将用户返回到他已经
  • 的页面