根据用户输入将列名作为参数传递给查询是否不好?

Is it bad to pass a column name as a parameter in a query, based on user input?

W3schools 和 Wikipedia 等许多参考文献状态 "If the original statement template is not derived from external input, SQL injection cannot occur"。

这到底是什么意思?我试图搜索更多有关该主题的内容,但大多数参考文献都停留在这一点上。

更具体地说,我说的是: 如果原始语句模板不是来自外部输入

作为,我已经研究了为什么它不会发生。

这是否意味着,只要您不直接将用户输入放入查询中,例如:

SELECT * FROM pubs WHERE " . $_POST['extra'] . " LIKE '%Yes%'

相对于:

SELECT * FROM pubs WHERE ? LIKE ?

此外,是否可以像我上面那样将列名作为参数传递。例如说我有

$extra = $_POST['extra'];
$yes = "%Yes%";

然后我准备:

$stmt = $mysqli->prepare(SELECT * FROM pubs WHERE ? LIKE ?);

然后绑定:

$stmt->bind_param("ss", $extra, $yes);

这个安全吗?

您不应在检查之前在查询中使用用户输入。此外,列名不能参数化,因此您的示例将不起作用。你应该做的是有一个允许的列名列表,并且只有当用户输入在接受列表中时才执行查询。

$allowedColumnNames = ['city', 'state', 'zip'];
if (in_array($_POST['extra'], $allowedColumnNames)) {
    //Perform your query.
    //SELECT * FROM pubs WHERE $_POST['extra'] LIKE ?
}