小编典典

在ADO.NET中,在SQL查询中可以使用SQL参数的地方是否有限制?

sql

这个问题仅出于教育目的,因为我目前尚未构建任何使用用户输入构建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查询不完整,我想知道问题是我尝试做的事情根本无法完成还是忽略了某些事情。


阅读 134

收藏
2021-04-14

共1个答案

小编典典

不可以,查询参数可以代替SQL语句中的 一个标量值
例如,单个字符串文字,日期文字或数字文字。

它不必在WHERE子句中。在SQL中可以有表达式的任何地方,都可以包含标量值,因此也可以包含参数。例如,在联接条件中,选择列表中或ORDER
BY或GROUP BY子句中。

不能 将查询参数用于:

  • 表标识符
  • 列标识符
  • SQL关键字
  • SQL表达式
  • 值列表(例如,在IN()谓词中)

如果需要使查询的这些部分中的任何部分都可由用户定义,则需要通过将应用程序变量内插或连接到字符串中来构建SQL查询字符串。这使得很难防御SQL注入。

在这种情况下,最好的防御方法是将可以安全插值到SQL字符串中的特定值 列入白名单
,例如,在代码中定义的一组表名。让用户从这些预先批准的值中选择一个表,但是不要在随后执行的SQL代码中逐字使用输入。

用户输入可以提供值,但绝不能提供代码。

您可能会发现我的演示文稿“ SQL注入神话和谬论”有帮助。我在该演示文稿中涵盖了白名单(我的示例使用PHP,但该想法适用于任何编程语言)。

2021-04-14