避免从C#代码在MSSQL Server上注入SQL的算法

本文关键字:注入 SQL 算法 Server MSSQL 代码 | 更新日期: 2023-09-27 17:47:46

在C#.net平台上避免SQL注入的最佳方法是什么。

如果你有C#实现,请发布一个。

避免从C#代码在MSSQL Server上注入SQL的算法

不需要任何算法,只是不要使用字符串串联来构建SQL语句。请改用SqlCommand.Parameters集合。这完成了所有必要的值转义(例如用''替换'),并确保命令是安全的,因为其他人(即Microsoft)已经完成了所有测试。

例如调用存储过程:

using (var connection = new SqlConnection("..."))
using (var command = new SqlCommand("MySprocName", connection))
{
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@Param1", param1Value);
    return command.ExecuteReader();
}

这种技术也适用于内联SQL语句,例如

var sql = "SELECT * FROM MyTable WHERE MyColumn = @Param1";
using (var connection = new SqlConnection("..."))
using (var command = new SqlCommand(sql, connection))
{
    command.Parameters.AddWithValue("@Param1", param1Value);
    return command.ExecuteReader();
}

为了安全,我们可以做的十件事(没有人能做到这一切。)

  1. 采用"所有数据都是邪恶的"的概念。所有数据,甚至存储在数据库或文件系统中的数据都是可疑的。不仅仅是来自防火墙外应用程序的数据输入,如查询字符串、表单字段、cookie等。任何东西都可能被用来危害系统。

  2. 不要依赖于javascript或html字段长度的客户端验证,甚至使用客户端验证的服务器端web API。使用它可以提高可用性,但不要把它当作唯一的保护。了解NET等API提供的验证器的工作方式。不要想当然。有办法绕过他们。

  3. 进行正匹配以在数据进入时捕获所有数据。如果数据与正则表达式的字符范围匹配,那么就可以了。这就不允许奇怪的unicode字符进入我们的数据库,这些字符可能会意外地在sql中定界,或者产生其他问题,如同源XSS/Phishing攻击。相反,负匹配需要列出所有不好的字符,这些字符似乎一直在增长。这是一个糟糕的方法。正匹配更好。我们拒绝坏数据,不净化或逃避它。

  4. 在可能的情况下,考虑使用"更新"、"删除"、"丢弃"、"选择"、"更改"等来过滤、标记或捕获字符串数据。考虑到字符串的性质,这可能是不可能的。"1212 Lemondrop Ln"、"Waltersburg,PA"answers"Table Rock,NE"是有效的地址字段。每天扫描所有表数据中与这些字段匹配的字段,可能会发现延迟攻击或漏洞。此外,当数据进入时,还可以使用日志记录、ip禁止、电子邮件警报等。

  5. 尽可能多地使用存储过程和/或参数化查询。避免在数据库客户端代码和sql中使用动态sql。(避免在存储过程中使用带有外部节的动态代码的exec语句!!)参数化将转义字符串终止符,如撇号、catch字段长度和类型检查。我们不能总是依赖提供完美参数化的API,但它们是由比我们大多数人更了解数据库特性的人编写的

  6. 请确保在可读/可执行的web目录中没有零散的代码。如果它不是活动站点的一部分,请将其归档到安全的地方,然后从公共视图中删除。未使用的存储过程也是如此。

  7. 随时了解数据库API的最新情况。在某些API中执行SQL语句的某些方法不如其他方法安全。

  8. 使用单向加密安全存储密码。通过这种方式,用户名和密码的表转储仍然可以将用户拒之门外。

  9. 用所有常用的方法加固服务器。例如,在可能的情况下,对数据库表给予最低权限。将web服务器数据库帐户的访问权限严格限制在有问题的表上。尽可能使用只读。创建多个帐户,在公共流量和内部/受信任流量的访问权限之间产生分歧。

  10. 优雅地捕捉错误。这适用于所有代码,而不仅仅是使用数据库的代码。然而,Sql注入攻击确实依赖于错误消息,因此最好尽可能多地向公众隐藏数据库。总是以普通的方式编写处理异常或空数据集的代码,以便尽可能少地透露我们正在使用的数据库类型、表中的字段或我们正在运行的查询类型。记录服务器上的错误。即使在非数据库代码中,也最好对第三方组件、文件夹结构、我们可能正在运行的其他服务等保持沉默。尽可能少地向软弱的用户提供信息是让他们一无所知的关键。

而#11,总是重新审视/修改这个列表。始终保持最新。积极主动。把它作为一个预先的优先事项和要求,而不是事后考虑。