这个问题仅用于教育目的,因为我目前没有构建任何使用用户输入构建SQL查询的应用程序。
那就是说,我知道在ADO.NET中你可以通过这样的方式阻止SQL注入:
OleDbCommand command = new OleDbCommand("SELECT * FROM Table WHERE Account = @2", connection);
command.Parameters.AddWithValue("@2", "ABC");
但假设您的应用程序的设计方式使用户可以实际输入表格的名称,您可以执行以下操作吗? (我不在乎是否允许用户提供表的名称是个坏主意,我只想知道以下是否可能......)
OleDbCommand command = new OleDbCommand("SELECT * FROM @1 WHERE Account = @2", connection);
command.Parameters.AddWithValue("@1", "Table");
command.Parameters.AddWithValue("@2", "ABC");
当我运行第二个代码时,我一直得到一个异常,说SQL查询是不完整的,我想知道问题是我想要做的事情根本无法完成或者我忽略了什么。< / p>
答案 0 :(得分:4)
不,查询参数可以替换SQL语句中的一个标量值。
例如,单个字符串文字,日期文字或数字文字。
它不必在WHERE子句中。您可以在SQL中拥有表达式的任何位置,您可以包含标量值,因此也可以包含参数。例如,在连接条件中,或在选择列表中,或在ORDER BY或GROUP BY子句中。
你无法使用查询参数:
如果您需要使查询的任何部分可由用户定义,则需要通过将应用程序变量插入或连接到字符串中来构建SQL查询字符串。这使得很难防止SQL注入。
在这种情况下,最好的防御是白名单可以安全插入到SQL字符串中的特定值,例如您在代码中定义的一组表名。让用户从这些预先批准的值中选择一个表,但不要在随后执行的SQL代码中逐字使用它们的输入。
用户输入可能会提供值,但绝不应提供代码。
您可能会发现我的演示文稿SQL Injection Myths and Fallacies很有帮助。我在该演示文稿中介绍了白名单(我的示例是在PHP中,但这个想法适用于任何编程语言)。