如果我们必须在SQL Server中动态使用表名,如何修复SQL注入?

问题描述 投票:0回答:1

这是代码中的实现:模式名称来自配置文件,并且每个环境都不同。 Sonar 对此语句抛出 SQL 注入警报:

select * 
from dbName.dbo.stu_name;     <<dbname is the variable that comes from property file>>

我尝试了这些解决方案:

  1. 使用

    query.setParameter(?,dbname)
    。尝试动态传递数据库名称并修复了漏洞。调试时,查询抛出错误并且未执行。

  2. 已使用

    String.format(select * from \'%s\',tablename.replace("\'","\'\'"))
    - 漏洞已修复,但查询无法执行

我尝试了各种其他解决方案,但没有任何效果。

有人可以帮我吗?

sql-server security sql-injection
1个回答
0
投票

您可以做的“最佳”防御是使用动态 SQL。考虑到这是动态的数据库,并且基于先前的问题,我会建议这是从应用程序中发生的,因此这意味着您不需要需要由三部分组成的命名。相反,您可以在连接字符串中参数化数据库名称并使用两部分命名;不需要动态 SQL。

如果您必须使用动态 SQL,那么“最佳™️”防御方法是验证数据库名称,然后确保在将数据库名称注入动态语句时正确引用数据库名称。

在这里,我验证

sys.databases
中的数据库名称,然后使用
QUOTENAME
适当地引用该名称。如果数据库不存在,则不会运行查询(并且不会返回错误):

DECLARE @DatabaseName sysname = N'YourDatabaseName';

DECLARE @SQL nvarchar(MAX);
SELECT @SQL = N'SELECT * FROM ' + QUOTENAME(d.name) + N'.dbo.stu_name;'
FROM sys.databases d
WHERE d.name = @DatabaseName;

EXEC sys.sp_executesql @SQL;
© www.soinside.com 2019 - 2024. All rights reserved.