【问题标题】:How do I prevent sql injection in dynamic sql for .Net Web APIs?如何防止 .Net Web API 的动态 sql 中的 sql 注入?
【发布时间】:2015-11-23 22:00:12
【问题描述】:

我只是没有找到任何我喜欢的答案。

我想做这样的事情:

public class TestSqlInjectionController : ApiController
{
    public IEnumerable<TestSqlInjectionUser> Get([ValidateSqlInjection]string usernameFilter = null)
    {

如果传入过滤器包含;--DROPDELETE[ValidateSqlInjection] 会查找基本信息,例如抛出错误。

所以我会有一个可维护的列表。

然后创建一个自定义属性:

[FilterField1ValidateSqlInjection]

这里可能会将一个逗号分隔的列表拆分成一个数组。

然后遍历数组并确保每个元素与枚举中的一个值匹配。

这听起来像是在朝着正确的方向前进吗?

问题是我们必须使用动态 SQL 进行大量的分页、排序和过滤。没有其他办法了。

所以命令参数对我们来说并没有什么作用。

对于任何有 .Net SQL 注入经验的人来说,自定义属性听起来是个好主意吗?

【问题讨论】:

  • 这是一种经典的黑名单方法 - 这是有缺陷的,因为注射器非常巧妙......每次添加另一个关键字或一组字符进行检查时,那些讨厌的攻击者已经准备好了 10 个攻击者——这是一场无望的上坡战斗。所以真的,你应该要么使用适当的技术,比如带有参数化查询的常规 SQL(我认为这是迄今为止首选的方法 - 它可以轻松处理分页、排序、过滤 - 相信我! ),或者您应该使用带有有效关键字列表的 白名单 方法
  • 你应该寻找user input escaping
  • usernameFilter 应该包含什么?为什么不接受字符串集合而不是单个字符串?

标签: c# .net asp.net-web-api sql-injection


【解决方案1】:

最好的选择是使用 SQL 参数,但由于这对你来说还不够,我会尝试使用类似模式的 SQL 执行器。

相反,您尝试使用属性来装饰所有可能的输入,创建一个帮助器类来负责执行所有动态查询,并在执行方法中测试它是否具有任何 SQL 注入模式。您可以使用正则表达式 like this example 执行此操作,如果发现则抛出异常。

在您的 UI 上,您可以捕获此异常并向您的用户显示一些输出。

【讨论】:

    【解决方案2】:

    为了完全安全和动态,您需要编写一个解析器来正确解析过滤器字符串,但我建议您使用动态 Linq 库,使用库方法,您的客户端代码实际上可以运行 EF 查询动态构建的 lambda 表达式本身是库方法通过解析用户输入字符串构造的。此方法生成只能在 ORDER BY、WHERE 或 SELECT 子句中使用的安全查询部分。

    以下是此类库的链接: https://github.com/NArnott/System.Linq.Dynamic

    这个库的一些文档: http://dynamiclinq.azurewebsites.net/GettingStarted#subValues

    【讨论】:

      【解决方案3】:

      面向方面是您的解决方案。 改变项目会太痛苦。 找到一个好的解析器来检查输入字符串是否有奇怪的行为,如果发现可疑字符串,则删除它。

      [CleanInputArgs]
      public void CallServer(string sqlarg) 
      {
          // logic...
      }
      
      public void CleanInputArgs(args)
      {
          // here is the thing. iterate over args and 
          // remove all suspicious strings that might be SQL injection
      }
      

      【讨论】:

        【解决方案4】:

        有许多可用的解决方案。以下是谷歌的一些热门搜索结果。

        https://msdn.microsoft.com/en-us/library/ff648339.aspx Control SQL injection in MVC http://devproconnections.com/net-framework/protecting-legacy-web-applications-antixss

        然而,处理 SQL 注入的最佳选择是不使用动态 SQL。今天有很多更好的工具可供您使用。有参数化的 SQL 语句和存储过程。但是,如果您的查询绝对必须是动态的,我建议您考虑使用 linq 和表达式树。

        https://msdn.microsoft.com/en-us/library/bb882637.aspx

        【讨论】:

        • 虽然我当然同意你的观点,但应该尽可能避免使用动态 SQL,但至少在少数情况下是无法避免的。
        • 我再次指向表达式树。可以构建不易受到注入攻击的动态 SQL 语句。只需查看答案中的最后一个链接。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-05
        • 2021-07-15
        • 2015-09-07
        • 2011-09-10
        • 2019-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多