将变量传递给 Openquery 和 SQL 注入

Passing variables into Openquery and SQL Injection

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

我必须能够使用数据库 A 上的存储过程将具有不同值的行插入到数据库 B 中的 table 中。此存储过程使用 OPENQUERY 来执行 INSERT 语句到数据库 B.

我知道 OPENQUERY not accept variables for its arguments. OPENQUERY has specific syntax 如何插入链接数据库:

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

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

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 中的 table 有两列,ID (int) 和 VALUE (nvarchar(max))

因此,对于能够将不同值插入数据库 B 中的 table 的存储过程,我的过程如下所示:

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'

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

有没有办法防止 SQL 注入 OPENQUERY

谢谢!

“hacky”方法是先将您的参数插入本地 table,然后使用 OPENQUERY.

执行 INSERT INTO ... SELECT

如果你的 SP 曾经被一个进程以同步方式调用,这一切都很简单:你可以有一个 table,你可以在其中插入值,然后执行 OPENQUERY 来获取它们,然后你从 table.

中删除这些值

如果并发是一项要求,那么您必须编写逻辑来创建唯一命名的 tables 等,这很快就会变得有些混乱。