PHP:准备 JSON 选择器以防止 MySQL 注入

问题描述 投票:0回答:1

为了防止 SQL 注入,为查询准备动态 MySQL JSON 选择器的最佳/正确方法是什么?举个例子,假设我想执行以下查询:

SELECT `key` ->> "$.key.path" AS `setting_value`
FROM `settings`
LIMIT 1

但我想让关键路径动态化,例如:

$sql = <<<SQL
    SELECT `key` ->> "{$path}" AS `setting_value`
    FROM `settings`
    LIMIT 1
SQL;

通过条件值,我可以使用 PDO 为准备好的语句构建 SQL,例如:

$sql = <<<SQL
    SELECT *
    FROM `settings`
    WHERE `other_field` = :field_val
    LIMIT 1
SQL;

$statement = $this->handle()->prepare($sql);
$statement->execute([':field_val' => 'some val']);
$records = $statement->fetchAll(PDO::FETCH_OBJ);

向我的数据库适配器(甚至我的辅助函数)添加类似以下内容似乎相当不优雅并且容易出现错误/问题:

    public function cleanJsonSelector(string $selector) : string {
        return preg_replace('/[^-\$a-zA-Z0-9_\[\].*\s]/', '', $selector);
    }

想法/帮助?

php mysql pdo sql-injection mysql-json
1个回答
0
投票

->
->>
运算符仅支持字符串文字。它们没有表达式、变量或参数。

但是您可以在等效的 JSON 函数中使用任何表达式(包括参数占位符)

JSON_EXTRACT()

->>
运算符就像
JSON_UNQUOTE(JSON_EXTRACT(json_doc, path))

$sql = <<<SQL
    SELECT JSON_UNQUOTE(JSON_EXTRACT(`key`, :path)) AS `setting_value`
    FROM `settings`
    LIMIT 1
SQL;

这似乎是 MySQL JSON 运算符功能中不必要的不一致,但这就是当前 MySQL 8.3 版本中的实现方式。

© www.soinside.com 2019 - 2024. All rights reserved.