English 中文(简体)
动态SQL更容易受到SQL注入/黑客攻击吗?
原标题:
  • 时间:2009-01-29 10:23:22
  •  标签:

Is Dynamic SQL more vulnerable to SQL Injection/hacking? If yes, how to prevent?

最佳回答

如果您使用参数而不是字符串连接来指定筛选条件,则不应易受 SQL 注入攻击。

例如:

做这个:

string sqlQuery = "SELECT * FROM Persons WHERE Persons.Name LIKE @name";

SqlCommand cmd = new SqlCommand ( sqlQuery );
...
cmd.Parameters.Add ("@name", SqlDbType.VarChar).Value = aName + "%";

不是这个:

   string sqlQuery = "SELECT * FROM Persons WHERE Persons.Name LIKE  " + aName + "% ";

第一个例子不容易遭受SQL注入攻击,但第二个例子很容易受到攻击。

The same applies for dynamic SQL that you use in stored procedures for instance. There, you can create a dynamic sql statement that uses parameters as well; You should then execute the dynamic statement using sp_executesql which enables you to specify parameters.

问题回答

快速回答是,如果你在你的应用程序中动态构建SQL,你必须意识到罪犯们会尝试的每一个小技巧。当你使用存储过程时,大部分工作将由你的供应商处理。

减少 SQL 注入机会的好方法是使用参数查询,如果不合适,请确保任何用户生成的字段都被剥离非字母字符。去掉引号、分号等。还要确保您的连接只有足够的访问权限来执行其需要的操作,如果您只查询数据,则创建一个仅允许选择、而不是更新和特别是不允许删除的用户/安全组。将 SQL 写入日志也是一个好习惯,这样您就知道人们在做什么,您可以调整和发现注入尝试。

在TSQL中,您应该使用sp_ExecuteSql来执行任何动态命令(例如,提供灵活的搜索/排序)。

请注意,除非您在证书方面跳过一些障碍,否则您仍需要直接 SELECT(等等)权限才能访问表(与 SPROC 不同,后者可以隐式提供访问权限),但它应该是防注入的。例如:

DECLARE @command nvarchar(4000), @name varchar(50)

SELECT @command =  SELECT * FROM [CUSTOMER] WHERE [Name] = @Name ,
       @name =  Fred 

EXEC sp_ExecuteSql @command, N @Name varchar(50) , @name

以上显然不需要使用动态SQL - 这只是为了说明!主要情况下,当您拥有多个可选搜索条件或灵活的ORDER BY子句(在SPROC内部)时才会有用。

在非TSQL客户端中,您可以通过命令参数实现相同的功能。

请注意,sp_ExecuteSql也利用过程缓存,因此比原始的EXEC (@command)更有效率。

这取决于您的查询有多动态。

如果您意味着存储动态值,那么只要按照Frederik的建议使用参数,这不是一个问题。

如果您的意思是根据动态标准构建查询,那您可能会有麻烦 :-)

例如,假设您有一个字符串字典,其中键是要更新的字段,项是新值。然后,您可以使用字典动态构建更新查询。如果黑客成功更改其中一个字段名称,他可能会成功插入自定义查询,从而入侵您的系统。

为了避免这种情况,你可以通过一些巧妙的验证字段名称的方法来解决。也许可以将其与表的列进行比较检查。但更安全的选择是使用一个固定的查询来更新所有值,并将原始值用于所有未更改的列。这样,您可以对值使用参数,这是安全的,而且您可以避免SQL注入攻击。

点击这里查看有关此主题的有趣讨论。





相关问题
热门标签