0

我有一种情况,我必须使用动态 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
4

1 回答 1

1
  1. 您可以使用只读用户,这至少会阻止任何更新。
  2. 寻找对您来说可疑的关键字:INSERT、UPDATE 等。
  3. 像这样使用第三方库

是一堆很好的抗注射技术。

于 2013-09-29T22:46:16.157 回答