【问题标题】:What's a good way to protect dynamic SQL code against injections on SQL Server?保护动态 SQL 代码免受 SQL Server 注入的好方法是什么?
【发布时间】:2014-01-15 09:32:39
【问题描述】:

我知道动态 SQL 永远不应该是第一选择,相信我它不是,但它现在正在起作用,我想找到一种方法,至少提供某种针对 SQL 注入的保护,任何东西总比没有好对吧?顺便说一句,我确实搜索了相关问题并找到了一堆,但没有使用 SQL Server 上的 SP。

在这个应用程序中需要动态 SQL 的原因是因为程序可以执行几个存储过程,但是它们可以从不同的数据库中选择信息,我们不知道它们将被命名为什么。我们确实知道这些数据库的名称将位于另一个数据库中,这就是用户部署以前系统的方式。

因此,当用户运行应用程序时,它会向他显示他可以访问的数据库,当他选择一个时,存储过程会通过动态 SQL 与所选数据库一起执行。

起初我以为唯一可以动态使用的参数是数据库,但看看参数是如何发送的,显然它们都是动态的,看看这个例子:

CREATE PROCEDURE testProc @myDatabase varchar(30), @myMonth varchar(10)
AS
BEGIN
DECLARE @sql nvarchar(1000)
SET @sql = 'SELECT * FROM '+@myDatabase+'.dbo.myTable WHERE Month='+@myMonth+''
EXECUTE sp_executesql @sql
END

现在这个应用程序将主要被那些最有可能不想放弃自己的数据库的人使用,但是他们将获得的选项将受到限制该应用程序允许他们创建更多字段来过滤数据,如果他们愿意,他们可以在这里或那里删除 drop。我不是说他们会,但它可能会发生,那么有没有办法让我至少从过程创建本身更安全一点?

【问题讨论】:

标签: sql-server-2008 stored-procedures sql-injection dynamic-sql


【解决方案1】:

您应该将sp_executesql 与参数一起使用,这是使用sp_executesql 而不是EXEC 执行动态SQL 的优势之一。此外,SQL Server 2008 中数据库名称的最大长度为 128 个字符,因此您可能需要相应地更改 @myDatabase 长度。我不确定是否可以在参数化命令字符串中将数据库名称作为变量插入,但您可以在执行SELECT 语句之前检查此类数据库是否存在。 你的情况是:

CREATE PROCEDURE testProc
    @myDatabase NVARCHAR(30),
    @myMonth VARCHAR(10)
AS
BEGIN

    DECLARE @sql NVARCHAR(1000)

    IF EXISTS (SELECT 1 FROM sys.databases AS db WHERE db.name = @myDatabase)
    BEGIN

        SET @sql = 'SELECT * FROM ' + @myDatabase + '.dbo.myTable WHERE Month=@myMonth';
        EXECUTE sp_executesql @sql, N'@myMonth VARCHAR(10)', @myMonth
    END

END
GO

当@myDatabase 与sys.databases.name 进行比较时,它应该是NVARCHAR,因为nameSYSNAME,它的类型是NVARCHAR(128)。从用户获取参数的动态 SQL 是不安全的,但如果您必须使用它,则应使用带参数的sp_executesql 过程。下面的书有一章描述了SQL注入和动态SQL的关系,下面是其中的一些引用:

从 T-SQL 开发人员的角度来看,这是最重要的之一 方法是通过参数化动态 SQL 的生成和执行 使用 sp_executesql

Querying Microsoft® SQL Server 2012,Itzik Ben-Gan、Dejan Sarka、Ron Talmage(第 456 页)。

参数化的能力意味着 sp_excutesql 避免了简单的 与 EXEC 语句中使用的连接类似。结果,它 可用于帮助防止 SQL 注入。

Querying Microsoft® SQL Server 2012,Itzik Ben-Gan、Dejan Sarka、Ron Talmage(第 458 页)。

【讨论】:

    猜你喜欢
    • 2021-03-19
    • 2016-06-16
    • 2016-05-31
    • 2011-02-03
    • 2020-05-06
    • 1970-01-01
    • 2016-11-17
    • 2013-03-12
    • 2010-12-24
    相关资源
    最近更新 更多