Jar*_*rgs 3 sql-server sql-injection
我知道这是非常危险的:
EXEC sp_executesql 'SELECT * FROM ' + @Table
Run Code Online (Sandbox Code Playgroud)
但是,这对 SQL 注入安全吗?
IF EXISTS(SELECT * FROM information_schema.tables WHERE TABLE_NAME = @Table) BEGIN
EXEC sp_executesql 'SELECT * FROM ' + @Table
END
Run Code Online (Sandbox Code Playgroud)
这里仍有注入的潜力。让我们假设:
该人可以调用此过程以从 中获取结果foo,但同时创建一个名为 的表[foo;drop table bar],然后foo;drop table bar作为参数值传入。它会通过你的检查,然后你会盲目地执行它。他们得到结果,foo但他们也会删除 table bar。
现在,这是一个非常人为的场景,您可能并不担心内部人员删除表,但他们也可以使用它来利用他们无权访问的数据,例如他们可以创建一个名为的表[foo;SELECT name,salary FROM dbo.Employees;]并最终有两个结果集,一个包含您可能不应该让他们看到的数据。
如果不同模式中存在具有相同名称的表,则还可能从错误的表中获取数据。在创建或引用对象时,始终,始终,始终使用架构前缀:
最后,不要使用INFORMATION_SCHEMA. 目录视图和元数据功能更加完整、最新和可靠:
我可能会这样做(为了简单起见,我将假设您的所有表都在 dbo 中):
DECLARE @table SYSNAME; -- procedure parameter, right?
DECLARE @sql NVARCHAR(MAX);
IF OBJECT_ID(N'dbo.' + QUOTENAME(@table), N'U') IS NOT NULL
BEGIN
SET @sql = N'SELECT * FROM dbo.' + QUOTENAME(@table) + ';';
EXEC sp_executesql @sql;
END
Run Code Online (Sandbox Code Playgroud)
这样,即使他们通过foo;drop table bar或foo;select name,salary from dbo.employees作为表名,整个字符串也会被方括号包围,因此可能发生的最糟糕的事情是他们将从他们创建的表中获得结果,而不是任何其他表或更糟。
而且我会确保该过程以该用户身份运行,而不是升级使用EXECUTE AS(正确权限配置的常见绕过)。另见:
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |