【问题标题】:Better $_GET security更好的 $_GET 安全性
【发布时间】:2017-08-15 04:48:25
【问题描述】:

我的 PHP 生锈了。我有一个 md5 哈希,它通过 get 传递给脚本,然后我像这样抓取它:

$id = $_GET['id'];

显然这里存在安全风险...我正在考虑检查字符串长度以确保其长度为 32 个字符,但这对我来说似乎不是很可靠。我还能做些什么来使它更安全?

谢谢

【问题讨论】:

  • 为什么要通过 get 传递哈希?如果没有更多信息,我猜你这样做的方式根本不安全。
  • 你拿到$id之后做什么?
  • 是否存在安全风险主要取决于您之后对变量的处理方式。
  • 这是电子邮件中的一个链接。用户单击它并被定向到一个页面,该哈希用于验证它们...调用数据库以查看是否有记录里面有那个哈希ID..如果有那么他们被允许更新他们的详细信息......正如我所说我的php生锈了但许多网站似乎都使用这种方法?
  • MD5 哈希可以有 16^32 个可能的值,因此只要用于生成哈希的输入数据是不可猜测的,它对于唯一链接就足够了。例如,对于密码更改请求(当用户忘记密码时),使用md5($userID . $userEmail . $_SERVER['REQUEST_TIME']) 就足够了,因为完全不可能猜测何时(request_time)以及哪个用户(用户 ID、电子邮件)要求更改密码。哈希本身也很难猜测,因为它可以有大量可能的值。

标签: php


【解决方案1】:

您可以使用正则表达式进行验证,以确保它仅包含字母数字字符。

例如像这样(我的 PHP 也生锈了):

if(preg_match("/^[A-Fa-f0-9]{32}$/", $id) > 0) {
    // All good
}

【讨论】:

  • 我刚刚注意到我的正则表达式错误(包括 A-Z) - 现在已经编辑了。
  • 这不匹配任何包含 32 个十六进制数字的字符串,而不仅仅是包含 32 个十六进制数字的字符串(我想你想要这样做)?假设输入是这样的,在两端锚定正则表达式。 ^[A-Fa-f0-9]{32}$.
  • 实际上这让我犯了一个错误:警告:preg_match() [function.preg-match]: Unknown modifier '{' in C:\wamp\www\winners.php on line 9 ...我的代码是这样的: if(preg_match("[A-Fa-f0-9]{32}", $_GET['id']) > 0) { $id = mysql_real_escape_string($_GET['id']) ; } 有什么想法吗?
  • @elduderino 正则表达式是有效的——你确定看对了吗?尝试用 / 包围模式,使其看起来像这样:/^[A-Fa-f0-9]{32}$/
  • 是的,现在排序。感谢您的帮助!
【解决方案2】:

首先我假设您使用的是 >= PHP5.2。我实际上建议您使用 PHP5.3,因为它甚至无需修改代码库就更快。我使用filter 扩展来保护我的代码库。

/* prevent XSS. */
$_GET   = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

【讨论】:

  • 这是解决方案,谢谢老兄
【解决方案3】:

您可以使用preg_match 来检查是否仅存在 alnum 和 32 长度。

【讨论】:

    【解决方案4】:

    这取决于你想用 id 做什么。如果你用这个创建一个mysql select,你应该添加mysql_real_escape_stringphp.net/mysql_real_escape_string)。出于输出目的,您可以使用 htmlentities (php.net/htmlentities) 将字符串转换为 html 实体或使用过滤器扩展 (php.net/filter)

    【讨论】:

      【解决方案5】:
      1. 制作某种“过滤器”并将它们应用于 $_GET['id'] var ,在这些过滤器中,您可以检查长度、类型、允许的字符类型、是否需要...

      2. 每次渲染表单时,将随机生成的字符串(散列)作为隐藏元素传递给表单,在生成时将字符串保存在会话中,并首先在表单 sumbit 检查,如果它们不匹配,那么您甚至不需要检查发送的 id 或其他元素。

      3. 尽可能使用 post 而不是 get。

      【讨论】:

        【解决方案6】:

        使用ctype-alnum的示例:

        if (strlen($id) == 32 && ctype_alnum($id)) exit('pass');
        else exit('no');
        

        【讨论】:

          【解决方案7】:

          【讨论】:

            猜你喜欢
            • 2012-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-31
            相关资源
            最近更新 更多