使用PHP的PDO安全删除SQL查询中的变量表名

时间:2012-11-21 18:06:54

标签: php mysql database pdo sql-delete

我正在尝试创建一个允许我删除表中某一行的函数。我想将函数用于几个不同的表,所以当我调用函数时,我会将函数的一个参数作为表名。以下是我正在尝试做的一个例子:

function delete($conn, $table, $id) {
    $stmt = $conn->prepare("DELETE FROM ".$table." WHERE id = :id");
    $stmt->bindParam(":id", $id, PDO::PARAM_INT);
    $stmt->execute();  

    if ($stmt->rowCount() > 0) {
            return true;
    } else {
            return false;
    }
}

我遇到的一个问题是,因为$ table变量直接进入SQL查询,我的数据库不会受到SQL注入的风险吗?

当我从其他一个问题中学习时,我不能只放:table并将其添加到bindParam函数中,所以我不知道如何使这个函数安全。任何想法??

3 个答案:

答案 0 :(得分:3)

清理表格数据

您可以定义要在函数中使用的列入白名单的表名列表:

$whitelist = array('table1', 'table2', ...)

然后使用:

$myTable= array_intersect_keys($table, array_flip($whitelist));

$myTable现在将是安全的。

答案 1 :(得分:0)

作为元数据的表名比行数据更受限制 - 因此清理表名应该比清理数据更可靠。通过这种方式,我可以在PDO之外进行消毒。

我们经常使用的是PHP include,它包含所有有效的表名作为数组定义,因此我们只需查找它 - 如果找不到它,并且include的文件年龄超过一小时,我们运行“SHOW TABLES”并重新创建包含,因此它非常自动化。

答案 2 :(得分:0)

MySQL目前不支持动态SQL字符串构建,但您可以尝试使用PDO准备好的语句(可能是冗余的,我知道的)表的白名单或可能的MySQL预处理语句。

$sql = "
PREPARE stmt FROM 
'DELETE FROM @tbl WHERE id = :id';
EXECUTE stmt USING :table;
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':table', $table);

这是未经测试的,但可能有所帮助。