SQL DDL 代码,避免 SQL 注入攻击

SQL DDL code to avoid SQL Injection Attacks

提问人:m_finn 提问时间:8/4/2021 更新时间:8/4/2021 访问量:320

问:

以下代码被突出显示为 SQL 注入攻击的安全漏洞。

StringBuilder sb = new StringBuilder();
sb.Append("DROP DATABASE IF EXISTS " + dbname);

String **sqlCommText** = sb.ToString();

using (SqlCommand command = new SqlCommand(**sqlCommText**, connection))
{

   connection.Open();

即 sqlCommText

我知道在 DML sql 上创建准备好的语句,例如插入和更新,但我认为这不适用于 DDL sql - 我无法将 dbname 参数化到 sql 中。

有什么建议应该如何解决这个问题吗?

C# 准备语句 sql-injection

评论

1赞 Camilo Terevinto 8/4/2021
不要信任 - 使用各种预定义/已知数据库名称的字典。否则,请选择数据库列表并匹配内存中的名称,然后删除dbname
4赞 Dan Guzman 8/4/2021
一般来说,执行 DDL 是一个安全问题,只需要从受信任的代码和数据源完成。
3赞 RBarryYoung 8/4/2021
好吧,您正在删除一个数据库,SQL 注入器可以用它做什么更糟糕的事情?删除整个数据库可能已经非常糟糕了。他们不必注入它,只是将名称更改为错误的数据库本身就是灾难性的。
2赞 Thom A 8/4/2021
考虑到具有数据库能力的东西往往具有相当高的权限,@RBarryYoung,我可以想到他们可以做的其他一些事情。DROP
3赞 RBarryYoung 8/4/2021
@Larnu 删除错误的数据库已经是一场灾难。防止注入并不足以使此代码“安全”。我的观点是,在这里防止注射非常容易。防止删除错误的数据库是另一回事,需要比我们更多的信息。

答:

5赞 RBarryYoung 8/4/2021 #1

在这里防止 SQL 注入非常简单:查询 SQL Server 上所有数据库的名称,如下所示:

SELECT name, QUOTENAME(name) as QName 
FROM sys.databases 
WHERE database_id > 4;

然后,在执行其余 SQL 代码之前,只需检查您的变量是否在查询返回的名称列表中,如果是,则在查询中使用相应的名称(这样可以防止数据库名称中的奇数字符,也可以防止称为潜伏注入的东西)。dbnameQName

但是,正如我在评论中提到的,停止注射是一个简单的问题。这里的难题是确保合法用户不会意外删除错误的数据库,更糟糕的是,不良行为者不会故意删除错误的数据库。

评论

2赞 ChrisBD 8/4/2021
难道不能将应用程序限制为仅允许执行存储过程的角色,从而限制可以删除的数据库,因为它可以在存储过程中指定,而不是由代码传入吗?
0赞 RBarryYoung 8/4/2021
@ChrisBD 是的,没错。但是,问题仍然存在,即如何指定哪些数据库可以删除,哪些数据库不能删除。这不是一个简单或容易的问题,肯定需要比我们目前拥有的更多的上下文/信息。
1赞 m_finn 8/5/2021
感谢大家的输入。这不是我的代码,我被要求调查安全问题。我认为最好回过头来质疑为什么首先这样做,也许可以考虑另一种解决方案。优秀的答案和洞察力@RBarryYoung