dwb*_*nks 10 c# sql sql-injection
public static bool TruncateTable(string dbAlias, string tableName)
{
string sqlStatement = string.Format("TRUNCATE TABLE {0}", tableName);
return ExecuteNonQuery(dbAlias, sqlStatement) > 0;
}Run Code Online (Sandbox Code Playgroud)
Bil*_*win 23
打击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
Run Code Online (Sandbox Code Playgroud)
现在,您可以将输入变量作为SQL参数传递给此查询.如果查询未返回任何行,则表示输入无效用作表.如果查询返回一行,则匹配,因此您可以更安全地使用它.
您还可以根据您定义的特定表的列表验证表名,以便您的应用截断,正如@John Buchanan 建议的那样.
即使在验证了tableName作为RDBMS中的表名存在之后,我也建议分隔表名,以防您使用带有空格或特殊字符的表名.在Microsoft SQL Server中,默认标识符分隔符是方括号:
string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);
Run Code Online (Sandbox Code Playgroud)
现在,如果tableName匹配真实表,您只会面临SQL注入的风险,并且您实际上在表的名称中使用方括号!
据我所知,您不能使用参数化查询来执行DDL语句/指定表名,至少不能在Oracle或Sql Server中使用.我要做的,如果我必须有一个疯狂的TruncateTable函数,必须安全sql注入将是一个存储过程,检查输入是一个可以安全截断的表.
-- Sql Server specific!
CREATE TABLE TruncableTables (TableName varchar(50))
Insert into TruncableTables values ('MyTable')
go
CREATE PROCEDURE MyTrunc @tableName varchar(50)
AS
BEGIN
declare @IsValidTable int
declare @SqlString nvarchar(50)
select @IsValidTable = Count(*) from TruncableTables where TableName = @tableName
if @IsValidTable > 0
begin
select @SqlString = 'truncate table ' + @tableName
EXECUTE sp_executesql @SqlString
end
END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2979 次 |
| 最近记录: |