如何在php中使用Postgresql的白名单和预处理语句?

时间:2016-06-20 10:40:25

标签: php postgresql prepared-statement whitelist

我知道我需要在我的php代码中实现白名单和预备语句。但我不知道如何使用Postgresql来实现这一点,我的代码真的有必要吗?我正在使用选择列表将用户选择的值传递给查询。

<?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);

?>

1 个答案:

答案 0 :(得分:2)

白名单

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

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

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

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

准备好的陈述

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

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