将变量传递到 Openquery 和 SQL 注入中

Passing variables into Openquery and SQL Injection

提问人:Iridium 提问时间:11/20/2020 最后编辑:marc_sIridium 更新时间:11/20/2020 访问量:1030

问:

我有两个数据库(A 和 B),都是 SQL Server,位于不同的服务器上。这些数据库与链接服务器连接。

我必须能够使用数据库 A 上的存储过程将具有不同值的行插入到数据库 B 的表中。此存储过程用于在数据库 B 中执行语句。OPENQUERYINSERT

我知道它不接受变量作为其参数。 对如何插入链接数据库有特定的语法OPENQUERYOPENQUERY

INSERT OPENQUERY (OracleSvr, 'SELECT name FROM joe.titles')  
VALUES ('NewTitle');  

尽管如此,MS 文档显示了一种将变量传递到链接服务器查询的方法,如下所示:

DECLARE @TSQL varchar(8000), @VAR char(2)

SELECT @VAR = 'CA'
SELECT @TSQL = 'SELECT * FROM OPENQUERY(MyLinkedServer,''SELECT * FROM pubs.dbo.authors WHERE state = ''''' + @VAR + ''''''')'

EXEC (@TSQL)

这就是问题所在。假设数据库 B 中的表有两列,() 和IDintVALUE (nvarchar(max))

因此,为了使存储过程能够将不同的值插入到数据库 B 中的表中,我的过程如下所示:

CREATE PROCEDURE openquery_insert
    @var1 int,
    @var2 nvarchar(max)
AS 
BEGIN
    SET NOCOUNT ON;

BEGIN
    DECLARE @SQL_string nvarchar(max)
    SET @SQL_string = 'insert openquery(LINKEDSERVER, ''SELECT ID, VALUE from TABLE'') VALUES ('
    + CAST(@var1 AS NVARCHAR(5)) + ', ' 
    + '''' + CAST(@var2 AS NVARCHAR(max)) + ''''
    + ')'
        
    EXEC sp_executesql @SQL_string
END
END

该过程可以称为

EXEC openquery_insert @var1 = 1, @var2 = 'asdf'

但是,如果是这样,SQL注入攻击就会成功。@var2' DROP TABLE B--

有没有办法防止SQL注入?OPENQUERY

  • 我无法控制参数的值以及何时调用该过程@var1@var2
  • 我无法在数据库 B 上创建函数或存储过程
  • 我必须使用OPENQUERY,我不能使用四部分命名来进行插入
  • 我必须在数据库 A 上使用存储过程

谢谢!

sql-server 存储过程 sql 注入 openquery

评论

0赞 6/27/2022
请注意 - 请记住,字符串文字的最大长度为 8K 个字符。OPENQUERY

答:

0赞 Alex 11/20/2020 #1

“hacky”方法是先将参数插入到本地表中,然后使用 .INSERT INTO ... SELECTOPENQUERY

如果您的 SP 被一个进程以同步方式调用,这一切都很简单:您可以有一个表,您可以在其中插入值,然后执行以获取它们,然后从表中删除这些值。OPENQUERY

如果并发性是必需的,那么你必须编写创建唯一命名表等的逻辑,这很快就会变得有些混乱。