提问人:Iridium 提问时间:11/20/2020 最后编辑:marc_sIridium 更新时间:11/20/2020 访问量:1030
将变量传递到 Openquery 和 SQL 注入中
Passing variables into Openquery and SQL Injection
问:
我有两个数据库(A 和 B),都是 SQL Server,位于不同的服务器上。这些数据库与链接服务器连接。
我必须能够使用数据库 A 上的存储过程将具有不同值的行插入到数据库 B 的表中。此存储过程用于在数据库 B 中执行语句。OPENQUERY
INSERT
我知道它不接受变量作为其参数。 对如何插入链接数据库有特定的语法:OPENQUERY
OPENQUERY
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 中的表有两列,() 和ID
int
VALUE
(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 上使用存储过程
谢谢!
答:
0赞
Alex
11/20/2020
#1
“hacky”方法是先将参数插入到本地表中,然后使用 .INSERT INTO ... SELECT
OPENQUERY
如果您的 SP 被一个进程以同步方式调用,这一切都很简单:您可以有一个表,您可以在其中插入值,然后执行以获取它们,然后从表中删除这些值。OPENQUERY
如果并发性是必需的,那么你必须编写创建唯一命名表等的逻辑,这很快就会变得有些混乱。
上一个:安全地执行动态 sql 查询
评论
OPENQUERY