我目前正在使用c#连接到链接的SQL Server。问题是参数化不起作用,因为我必须在命令SQL字符串中使用openquery。
这对我来说意味着(据我所知)我遇到了我需要做的不应该做的事情......设置手动设置为避免使用SQL注入而不是使用参数化的SQL命令。
我所拥有的是参数本身及其需要确保的值。
例如:
"SELECT * FROM OPENQUERY(LOCALSERVER, 'SELECT * FROM accounts where accountNumber=@accountNumber and Client=@client')"
参数帐号的值 100-200-300-400 ,客户的值' MIP'
所以我的问题是:是否有最常见的攻击路线列表以及如何对抗它们?
(或者我可以采取其他任何途径,因为最常见的路线不适合我吗?)
答案 0 :(得分:4)
来自https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet。
您有以下几种选择:
选项1:白名单输入验证
请转到https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet查看建议白名单。
SQL查询的各个部分不是使用绑定变量的合法位置,例如表或列的名称,以及排序顺序指示符(ASC或DESC)。在这种情况下,输入验证或查询重新设计是最合适的防御。对于表或列的名称,理想情况下,这些值来自代码,而不是来自用户参数。但是,如果用户参数值用于使表名和列名不同,则应将参数值映射到合法/预期的表或列名,以确保未经验证的用户输入不会在查询中结束。请注意,这是设计不佳的症状,如果时间允许,应考虑完全重写。以下是表名验证的示例。
String tableName;
switch(PARAM):
case "Value1": tableName = "fooTable";
break;
case "Value2": tableName = "barTable";
break;
...
default : throw new InputValidationException("unexpected value provided for table name");
选项2:转义所有用户提供的输入
当上述任何一种方法都不可行时,此技术仅应作为最后的手段使用。输入验证可能是一个更好的选择,因为与其他防御相比,这种方法很脆弱,我们无法保证它会在所有情况下阻止所有SQL注入。
此技术是在将用户输入放入查询之前将其转义。它的实现在数据库方面非常具体。在实施输入验证时,通常只建议改进遗留代码并不具有成本效益。应该使用参数化查询,存储过程或某种为您构建查询的对象关系映射器(ORM)来构建或重写从头开始构建的应用程序或需要低风险容忍度的应用程序。
这种技术就像这样。每个DBMS都支持一种或多种特定于某些查询的字符转义方案。如果您使用正在使用的数据库的正确转义方案转义所有用户提供的输入,则DBMS不会将该输入与开发人员编写的SQL代码混淆,从而避免任何可能的SQL注入漏洞。
OWASP企业安全API(ESAPI)是一个免费的开源Web应用程序安全控制库,使程序员可以更轻松地编写风险较低的应用程序。 ESAPI库旨在使程序员更容易将安全性改进现有应用程序。 ESAPI库也是新开发的坚实基础。
其他行动: 具有多个数据库用户和视图的最低权限