如何在 php 中使用 Postgresql 的白名单和准备语句?

How to use whitelists and prepared-statements with Postgresql in php?

我知道我需要在我的 php 代码中实现白名单和准备语句。但是我不确定如何使用 Postgresql 执行此操作,我的代码真的有必要吗?我正在使用 select 列表将用户 selected 值传递给查询。

<?php

include "connect.php";

$table          = $_POST['tableSelected'];
$field          = $_POST['fieldSelected'];
$attribute      = $_POST['attributeSelected'];
$operator       = $_POST['operatorSelected'];
$fieldList      = $_POST['fieldList'];

$fieldstr = $fieldList . ",ST_AsGeoJSON(ST_Transform(l.geom,4326))";


$sql = "SELECT $fieldstr
        FROM $table l";

if (!empty($field) && !empty($operator) && !empty($attribute)) {
    $sql .= " WHERE {$field} {$operator} '{$attribute}'";
}

echo ($sql);

?>

白名单

您当前形式的代码非常危险,您不仅允许用户决定应选择哪些字段,而且还允许他决定查询哪些 table。你一定要对这些进行白名单检查。例如:

if($_POST['tableSelected'] == 'acceptable_table1' || $_POST['tableSelected'] == 'acceptable_table2) {
    $table = $_POST['tableSelected']
}

同样,您应该验证字段列表。但是字段列表验证将变得相当复杂,因为您的字段将依赖于 table。我建议创建数组并检查选择是否在其中。

$table1_fields = array('col1','col2',...)
$table2_fields = array('col1','col2',...)

准备好的语句

众所周知,预处理语句只能用于绑定参数。它们不能用于填写 table 名称和列名称。这就是为什么您需要准备好的语句和白名单。我建议使用 PDO。它可能看起来像

$stmt = $dbh->prepare("SELECT {$fieldlist} FROM {$table} where field = ?");
$stmt->execute(array('somevalue'));