public static bool TruncateTable(string dbAlias, string tableName) { string sqlStatement = string.Format(“TRUNCATE TABLE {0}”, tableName); return ExecuteNonQuery(dbAlias, sqlStatement) > 0; }
对抗SQL注入的最常见建议是使用SQL查询参数(此线程上的许多人都建议使用此参数)。
在这种情况下,这是错误的答案。 您不能在DDL语句中为表名使用SQL查询参数。
SQL查询参数只能代替SQL表达式中的文字值使用。这在SQL的每个实现中都是标准的。
对于具有表名的情况,我建议防止SQL注入是针对已知表名的列表验证输入字符串。
您可以从中获取有效表名的列表INFORMATION_SCHEMA:
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中,默认标识符定界符为方括号:
tableName
string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);
现在,只有tableName与实际表匹配时才有SQL注入的风险,并且实际上在表名中使用方括号!