【问题标题】:Dynamic Prepared Statements - Does this open security holes?Dynamic Prepared Statements - 这会打开安全漏洞吗?
【发布时间】:2012-07-05 14:28:35
【问题描述】:

这类似于这个问题 - Are Dynamic Prepared Statements Bad? (with php + mysqli),但是因为它已经 4 岁了,我想得到一个更新的答案。

我写了一个类,虽然我没有在更多的 coplex sql 查询上对其进行测试,但它在简单的 sql 查询上也能正常工作,但是我不确定这样做是否绕过了其中一个主要原因对于准备好的语句 - 安全性。

我已经使用了call_user_func_array,使用bind_param 语句很容易,但是使用bind_result 有点棘手。我最初使用get_result,但是我使用的主机没有mysqlnd,但我设法使用元数据。这是我写的完整课程。

你认为这安全吗?

传入的值为:

  • $sql是传入的sql语句:

    SELECT * FROM users WHERE id = ? AND created_timestamp > ?
    
  • $mysqli是mysqli连接

  • $para 是准备好的语句中的占位符:

    array ($types = 'ii', 23, 1235376000)
    

班级:

class crudModel {
    function ps($sql, $mysqli, $para) {
        //this function should work for just about any simple mysql statement
        //for more complicated stuff like joins, unions etc,. we will see
        if ($prep = $mysqli->prepare($sql)) {
            call_user_func_array(array($prep, 'bind_param'), $this->makeValuesRef($para, $mysqli));
            $prep->execute();
            $meta = $prep->result_metadata();
            while ($field = $meta->fetch_field()) {
                $parameters[] = &$row[$field->name];
            }
            call_user_func_array(array($prep, 'bind_result'), $parameters);
            while ($prep->fetch()) {
                foreach ($row as $key=>$val) {
                    $x[$key] = $val;
                }
                $data[] = $x;
            }
            return $data;
        }
    }

    function makeValuesRef($array, $mysqli) {
        $refs = array();
        foreach($array as $key => $value) {
            $array[$key] = $mysqli->real_escape_string($value); //i don't think escaping is necessary, but it can't hurt (??)
            $refs[$key] = &$array[$key];
        }
        return $refs;
    }
}

【问题讨论】:

  • $sql 来自哪里?
  • 如果您使用 PDO 而不是 mysqli,您的代码将变得更加可移植,因为 PDO 对象层与大多数 DBMS 兼容,而不仅仅是 MySql。
  • $sql 来自另一个类。目前我只使用简单的 sql 语句来测试这个类,连接是我用过的最复杂的东西。即 $sql = "SELECT * FROM users INNER JOIN others ON (users.id = others.user_id) WHERE others.id = ?"
  • 刚刚开始使用 PDO,所以也会研究一下
  • 但是$sql起源是从哪里来的呢?它是否 100% 在您的控制之下,并且您可以确定没有恶意 SQL 被注入其中?或者它的某些部分(可能是表或列标识符)是否源自您的应用程序外部?

标签: php mysql security prepared-statement


【解决方案1】:

您在这里所做的不是动态准备好的语句。您只是在 MySQLi API 之上添加了一些语法糖(这很糟糕)。

简而言之,您在此处显示的代码并不存在任何安全问题。事实上,这种做法非常好,因为它可以更容易地在以后验证您是否正确执行此操作(因为 MySQLi API 很烂)。

所以你没事。我会担心您正在生成查询的区域,并确保您不会在没有列入白名单的情况下不小心将用户数据放入其中...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 2017-11-24
    相关资源
    最近更新 更多