这是代码中的实现:模式名称来自配置文件,并且每个环境都不同。 Sonar 对此语句抛出 SQL 注入警报:
select *
from dbName.dbo.stu_name; <<dbname is the variable that comes from property file>>
我尝试了这些解决方案:
使用
query.setParameter(?,dbname)
。尝试动态传递数据库名称并修复了漏洞。调试时,查询抛出错误并且未执行。
已使用
String.format(select * from \'%s\',tablename.replace("\'","\'\'"))
- 漏洞已修复,但查询无法执行
我尝试了各种其他解决方案,但没有任何效果。
有人可以帮我吗?
您可以做的“最佳”防御是不使用动态 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;