5

这是我在这里的第一篇文章,我对编程世界也比较陌生。简而言之,在结束我使用 php、mysql 和 javascript/jquery 开发的电子商务网站时,我发现我构建所有查询的方式(使用 mysql_connect)可能会导致 mysql 注入和许多其他讨厌的事情事物。

试图将所有内容“转换”为更安全的 mysqli 准备语句方式,我编写了一个包含从数据库中检索信息所需的所有方法的类,但我不确定我正在制作的方式查询。

一些代码:类构造函数

class Database {

    private $DBH;

    public function __construct() {
        $this->DBH = new mysqli(WEB_SERVER, WEB_USER, WEB_PASS, WEB_NAME);
        if ($this->DBH->connect_errno) {
            return "Failed to connect to MySQL: (" . $this->DBH->connect_errno . ") " . $this->DBH->connect_error;
            exit();
        }
    }
    ...
}

...和一个查询示例:

public function get_record_by_param($record, $param, $value) {
    $stmt = $this->getDBH()->stmt_init();

    $query = "SELECT * ";
    $query .= "FROM {$record} ";
    $query .= "WHERE {$param} = {$value} LIMIT 1";

    if($stmt->prepare($query)){
        return $this->execute_simpleAssoc($stmt);
    } else {
    return "Prepare failed: (" . $this->getDBH()->errno . ") " . $this->getDBH()->error;
    }
}

使用这样的查询仍然安全吗?还是我一定需要使用 bind_param 方法?

希望我没有混淆,谢谢您的任何建议。

4

2 回答 2

3

不,它不安全。mysqli 无法解析查询字符串中的哪些是(可能易受攻击的)数据,哪些不是。

如果您希望数据转义,则需要分别绑定每个参数。

但是,绑定参数仅适用于数据。对于列名,您需要应用@Michael 在他的评论中指出的白名单。无法自动转义列/表名。

这适用于所有数据库层,包括 PDO。如果您为图层提供完整的查询字符串,则其中的数据不会被神奇地转义。

于 2013-01-07T12:29:39.863 回答
0

好吧,这更像是一个术语问题。看,有

  • 占位符的一般概念,用于在查询中表示您的数据
  • 准备好的语句,它是占位符的子集
  • 绑定的东西,属于准备好的语句,但可以省略

最有可能在“绑定”下您的意思是准备好的陈述。在这种情况下,答案可能会有所不同。
但是如果您采用占位符的想法,答案将会改变:
您运行查询的方式当然仍然不安全。
但是可以在没有(手动)绑定的情况下进行完全安全的查询。
因此,不需要 bind_param。

于 2013-01-07T12:46:55.763 回答