我可以在准备好的语句中参数化表名吗?


71

我已经多次使用mysqli_stmt_bind_param函数。但是,如果我分开试图防止SQL注入的变量,则会遇到错误。

这是一些代码示例:

function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO " .$new_table . " VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}

是否可以通过某种方式.$new_table.用另一个问号语句替换串联,制作另一个绑定参数语句或添加到现有的语句中以防止SQL注入?

像这样或某种形式:

function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{    
    $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}

5
不,参数化查询不只是将参数值放入查询字符串中,它还向RDBMS提供参数化查询和参数。但是这样的查询不能将表名或字段名作为参数。唯一的方法就是将表名动态编码为查询字符串,就像已经完成的那样。如果此字符串可能受到攻击,则应首先对其进行验证;例如针对允许的表格的白名单。
MatBailie 2012年

使用mysqli扩展名是安全的,继续!但是不要忘记对所有字符串进行清理和验证。
deepcell

您想用来消毒的任何特定功能吗?
GK1667

2
@ user1475765在表名上使用转义功能不会保护您免受任何侵害,请使用白名单。
jeroen 2012年

Answers:


86

对您的问题的简短回答是“否”。

从最严格的意义上讲,在数据库级别,准备好的语句仅允许将参数绑定到SQL语句的“值”位。

一种思考的方式是“可以在语句的运行时执行而不替换其含义的事物”。表名不是这些运行时值之一,因为它确定SQL语句本身的有效性(即,哪些列名有效),并且在执行时对其进行更改可能会更改SQL语句是否有效。

在较高的级别上,即使在模拟准备好的语句参数替换而不是实际将准备好的语句发送到数据库的数据库接口中(例如PDO),也可以想象到,这可以允许您在任何地方使用占位符(因为占位符在发送到表中的占位符的值将是一个字符串,并包含在发送给数据库的SQL中,这样SELECT * FROM ?mytable参数实际上将最终发送SELECT * FROM 'mytable'到数据库中,这是无效的SQL。

您最好的选择就是继续

SELECT * FROM {$mytable}

但是绝对应该有一个白名单的表,如果您$mytable来自用户输入,则首先要对其进行检查。


很好的建议,但以我的经验,这不适用于较大的动态网站。如果您的站点具有多用户设置,庞大且不断更新的广告资源等,那么此解决方案将很难应用。
Igal Zeifman

14
网站的大小与表的数量以及知道最终用户可以通过via参数直接查询哪些表无关。最终,这是一个奇怪的网站,最初让最终用户可以这样做。
山姆·格雷厄姆

0

(最新答案,请参阅我的旁注)。

尝试创建“数据库”时,适用相同的规则。

您不能使用准备好的语句来绑定数据库。

即:

CREATE DATABASE IF NOT EXISTS ?

不管用。请改用安全清单。

旁注:我添加了此答案(作为社区Wiki),因为它通常用于结束问题,有些人在试图绑定数据库而不是表和/或列时发布了与此类似的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.