根据用户输入在查询中传递列名作为参数是不是很糟糕


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

许多引用,如W3schools和Wikipedia,都表示"如果原始语句模板不是从外部输入派生的,则无法进行SQL注入"。

这到底意味着什么?我试着搜索更多关于这个主题的内容,但大多数参考文献都是这样。

更具体地说,我指的是:如果原始语句模板不是从外部输入派生的

正如,我已经研究过为什么它不能发生。

这是否意味着,只要你不直接将用户输入到查询中,比如:

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 ?
}