1

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

我编写了一个类,虽然我还没有在更多的 coplex sql 查询上对其进行测试,但它在简单的 sql 查询上没有失败,但是我不确定这样做是否绕过了准备好的语句的主要原因之一- 安全。

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

你认为这安全吗?

传入的值是:

  • $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;
    }
}
4

1 回答 1

1

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

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

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

于 2013-06-21T00:27:24.333 回答