如何在SQL Server中清理动态SQL-防止SQL注入 [英] How to cleanse dynamic SQL in SQL Server -- prevent SQL injection

查看:115
本文介绍了如何在SQL Server中清理动态SQL-防止SQL注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有大量依赖于动态SQL的SQL Server存储过程。

We have a ton of SQL Server stored procedures which rely on dynamic SQL.

存储过程的参数在动态SQL语句中使用。

The parameters to the stored procedure are used in a dynamic SQL statement.

我们需要在这些存储过程中使用标准验证函数来验证这些参数并防止SQL注入。

We need a standard validation function inside these stored procedures to validate these parameters and prevent SQL injection.

假设我们有这些约束:


  1. 我们无法重写不使用动态SQL的过程

  1. We can't rewrite the procedures to not use Dynamic SQL

我们不能使用sp_OACreate等来使用正则表达式进行验证。

We can't use sp_OACreate etc., to use regular expressions for validation.

我们无法修改调用在将参数传递给存储过程之前先验证存储过程。

We can't modify the application which calls the stored procedure to validate the parameters before they are passed to the stored procedure.

是否存在一组字符,我们可以过滤掉以确保我们不会受到SQL注入的影响?

Is there a set of characters we can filter out to ensure we are not susceptible to SQL injection?

推荐答案

我相信您需要担心三种不同的情况关于:

I believe there are three different cases that you have to worry about:


  • 字符串(任何需要引号的ing):''''+ replace(@string,``'','''''')+''''

  • 名称(不允许使用引号的任何内容): quotename(@string)

  • 不能进行的操作引号:这需要将白名单

注意所有在字符串变量中( char varchar nchar ,<$ c $来自用户控制来源的c> nvarchar 等)必须使用上述方法之一。这意味着即使您希望是数字的东西都存储在字符串变量中,也要加上引号。

Note: Everything in a string variable (char, varchar, nchar, nvarchar, etc.) that comes from user-controlled sources must use one of the above methods. That means that even things you expect to be numbers get quoted if they're stored in string variables.

有关更多详细信息,请参见 Microsoft杂志 (已过时链接:2016-10-19)

For more details, see the Microsoft Magazine (Obsolete link: 2016-10-19).

以下是使用所有三种方法的示例:

Here's an example using all three methods:

EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
     REPLACE(@salary, '''', '''''') +   -- replacing quotes even for numeric data
     ''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' +  -- quoting a name
     CASE @sort_dir WHEN 'DESC' THEN 'DESC' END     -- whitelisting


列入白名单

还请注意,通过在 EXEC 语句中内联所有字符串操作,无需担心截断问题。如果将中间结果分配给变量,则必须 确保变量足够大以容纳结果。如果执行 SET @result = QUOTENAME(@name),则应定义 @result 至少保留258(2 * 128 + 2)个字符。如果执行 SET @result = REPLACE(@str,``'',``''''),则应定义 @result 的大小是 @str 的两倍(假设 @str 中的每个字符都可能是引号)。当然,保存最终SQL语句的字符串变量必须足够大,以容纳所有静态SQL以及所有结果变量。

Also note that by doing all the string operations inline in the EXEC statement there is no concern with truncation problems. If you assign the intermediate results to variables, you must make sure that the variables are big enough to hold the results. If you do SET @result = QUOTENAME(@name) you should define @result to hold at least 258 (2 * 128 + 2) characters. If you do SET @result = REPLACE(@str, '''', '''''') you should define @result to be twice the size of @str (assume every character in @str could be a quote). And of course, the string variable holding the final SQL statement must be large enough to hold all the static SQL plus all of the result variables.

这篇关于如何在SQL Server中清理动态SQL-防止SQL注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆