【问题标题】:How do i make $_GET more secure.?我如何使 $_GET 更安全。?
【发布时间】:2010-09-10 05:42:12
【问题描述】:

我正在使用 get 方法执行一些操作,例如,批准,markasspam,删除,用于评论系统。我知道走这条路很不安全,但我无能为力。因为使用 $_GET 方法的原因是使用 PHP_SELF 在页面本身内执行操作,仅供参考,我也使用使用复选框的 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);
}

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

我该怎么做?您对此有何看法?

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

代码并不准确,它只是让您了解我想要实现的目标的示例。

【问题讨论】:

  • 请不要告诉我这是生产代码。
  • 请澄清一下,为什么不能使用 POST 在页面本身内执行操作?
  • @NullUserException 不幸的是,你看我是一个初学者学习的东西。是的,我不能在这个项目中使用。我将不胜感激并欢迎任何形式的反馈或建议:)
  • @Anton for post 我需要使用表单,并且我已经将它用于相同的元素。它会与我的代码相矛盾。
  • @Peter 我肯定会做的,谢谢。 :)

标签: php get security


【解决方案1】:

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

我会说你有两个选择:

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

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

重新编辑:

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

更进一步的做法是为每个操作创建临时哈希值,这是抵御多种外部攻击的终极保护。

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

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

为未使用的哈希添加一个超时函数(加上删除任何实际使用的哈希),你就完成了。

【讨论】:

  • @Pekka 仅供参考,此操作仅由经过身份验证的用户执行。我想避免事故和实验,这就是为什么我想让它更安全,是的,我将使用 .htaccess,但现在我需要知道在这个脚本中是否有任何方法可以生成哈希并使用 $_GET 进行比较并执行操作。
  • @Ibrahim 是什么阻止未经身份验证的用户输入 URL page.php?delete=1
  • POST 更加安全,当我们谈论在您的管理界面上的 XSS 攻击时。
  • @Anton POST 如何阻止 XSS?
  • @Anton 你是对的,但这就是所谓的 CSRF(见我的回答)。 XSS 是一个不同的漏洞。
【解决方案2】:

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

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

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

但是您应该尝试验证参数的内容是否真的是整数,而不是仅仅对它们进行 int_val'ing 并直接在数据库上使用它们。

关于您的编辑

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

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

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

【讨论】:

  • 对不起,我忘了说我已经给了用户认证,只有管理员才能执行操作。
  • @quantumSoup 这个问题已经演变。在被问到时,有问题的脚本似乎完全不受保护地访问所有管理功能,在这种情况下,使用 GET 还是 POST 真的无关紧要。当问题的上下文完全改变时,否决答案有点不公平 - 一个简单的评论就足够了。
【解决方案3】:

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

如果你不能使用表单作为操作按钮(因为在它们之外还有另一个表单)你应该考虑这种设计:

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

【讨论】:

  • 是否有任何 JQuery 插件可以做到这一点?
  • 它在 JQuery 中,没有任何插件。阅读 $.post() 或 $.ajax() 中的文档
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多