我有一种情况,我必须使用动态 SQL,因为它看起来很难使用参数。
我将动态执行的查询如下。 验证 @sql 中的字符串是否存在恶意 SQL 的最佳方法是什么?我需要允许像“CountryId = 23”这样的有效字符串,但不允许像“从国家/地区删除”这样的字符串。我不希望一切都不允许。
我正在使用 C# 对 SQL Server 2008 R2 运行此查询。
也许,我可以在 SQL 级别或 C# 级别进行验证,但我不确定哪个会更好。
SET @sql = 'SELECT * from Customers
where ' + @filterExpression +
' order by ' + @sortExpression;
EXEC sp_executesql @sql
更新:对于必须使用动态 SQL 的情况,Maxim 的答案似乎是最好的,尽管应该尽可能避免像我在这篇文章中使用的代码这样的动态 SQL。
我对 T-SQL 中的变量 @filterExpression 进行了一些验证,以验证恶意 SQL 代码,这可能仍然会遗漏一些恶意案例,但这是我想出的 T-SQL。
IF PATINDEX('%DELETE %', @filterExpression ) > 0
OR PATINDEX('%SELECT %FROM%', @filterExpression ) > 0
OR PATINDEX('%;%', @filterExpression ) > 0
OR PATINDEX('%DROP %', @filterExpression ) > 0
OR PATINDEX('%CREATE %', @filterExpression ) > 0
OR PATINDEX('%TRUNCATE %', @filterExpression ) > 0
OR PATINDEX('%sys%', @filterExpression ) > 0
OR PATINDEX('%INDEX %', @filterExpression ) > 0
OR PATINDEX('%UPDATE %', @filterExpression ) > 0
OR PATINDEX('%INSERT %', @filterExpression ) > 0
OR PATINDEX('%EXEC %', @filterExpression ) > 0
OR PATINDEX('%EXECUTE %', @filterExpression ) > 0
OR PATINDEX('%CAST%', @filterExpression ) > 0
OR PATINDEX('%DECLARE %', @filterExpression ) > 0
OR PATINDEX('%CONVERT%', @filterExpression ) > 0
BEGIN
RETURN;
END