一尘不染

如何保护此功能免于SQL注入?

sql

public static bool TruncateTable(string dbAlias, string tableName)
{
string sqlStatement = string.Format(“TRUNCATE TABLE {0}”, tableName);
return ExecuteNonQuery(dbAlias, sqlStatement) > 0;
}


阅读 140

收藏
2021-03-10

共1个答案

一尘不染

对抗SQL注入的最常见建议是使用SQL查询参数(此线程上的许多人都建议使用此参数)。

在这种情况下,这是错误的答案。 您不能在DDL语句中为表名使用SQL查询参数。

SQL查询参数只能代替SQL表达式中的文字值使用。这在SQL的每个实现中都是标准的。

对于具有表名的情况,我建议防止SQL注入是针对已知表名的列表验证输入字符串。

您可以从中获取有效表名的列​​表INFORMATION_SCHEMA

SELECT table_name 
FROM INFORMATION_SCHEMA.Tables 
WHERE table_type = 'BASE TABLE'
  AND table_name = @tableName

现在,您可以将输入变量作为SQL参数传递给此查询。如果查询不返回任何行,则说明输入无效,不能用作表。如果查询返回一行,则表示该行已匹配,因此您可以确保可以安全使用它。

您还可以根据您定义的可以将应用程序截断的特定表的列表来验证表名,如@John
Buchanan所建议的那样

即使在验证了tableNameRDBMS中作为表名存在的表名之后,我也建议对表名进行定界,以防万一您使用带空格或特殊字符的表名。在Microsoft
SQL Server中,默认标识符定界符为方括号:

string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);

现在,只有tableName与实际表匹配时才有SQL注入的风险,并且实际上在表名中使用方括号!

2021-03-10