【问题标题】:Dynamic LINQ with direct user input, any dangers?具有直接用户输入的动态 LINQ,有什么危险吗?
【发布时间】:2010-10-01 02:56:38
【问题描述】:

我在 ASP.NET MVC 应用程序中有一个表,我希望它可以使用 AJAX 进行排序(服务器端)和过滤。我希望它在其他地方相当容易使用,并且不想将排序和过滤硬编码到查询表达式中,所以我寻找一种动态构建表达式的方法,我发现最好的方法是使用 Dynamic LINQ .

来自如下 URL 的用户输入直接插入到动态 Where 或 OrderBy 中。

/Orders?sortby=OrderID&order=desc&CustomerName=Microsoft

这将导致两个表达式:

OrderBy("OrderID descending")
Where(@"CustomerName.Contains(""Microsoft"")")

虽然我知道它不会直接扔到数据库中并且在此处插入直接 SQL 将不起作用,因为它不能反映到属性并且它是类型安全的,我想知道是否还有更多人无论如何,比我更有创造力的人可以找到一种利用它的方法。我能想到的一个利用是可以对表中不可见的属性进行排序/过滤,但这并不是那么有害,因为它们仍然不会显示并且可以通过散列来防止。

我允许用户直接输入的唯一方法是使用 OrderBy 和 Where。

只是确保,谢谢:)

【问题讨论】:

    标签: c# linq sql-injection dynamic-linq


    【解决方案1】:

    由于 LINQ to SQL 使用类型安全的数据模型类,默认情况下您可以免受 SQL 注入攻击。 LINQ to SQL 将根据基础数据类型自动对值进行编码。
    (c) 斯科特古

    但是你仍然可以在那里得到“除以零”,因此建议处理所有意外异常并限制有效条目的长度,JIC

    【讨论】:

      【解决方案2】:

      嗯...我刚刚发现至少一个 Dynamic Linq 可能存在的问题。只需执行这个 sn-p 1000 次,然后观察 CPU 和内存消耗是否会上升(为拒绝服务攻击创建一个简单的方法):

      var lambda = DynamicExpression
        .ParseLambda<Order, bool>("Customer=string.Format(\"{0,9999999}"+
           "{0,9999999}{0,9999999}{0,9999999}{0,9999999}\",Customer)")
        .Compile();
      
      var arg = new Order
      {
        Total = 11
      };
      Console.WriteLine(lambda(arg));
      

      我在上面写了blog post

      【讨论】:

      • 我认为这是最相关的答案。
      【解决方案3】:

      只是一个想法,但是您看过 ADO.NET 数据服务吗?这提供了一个支持 REST 的 API,与上面非常相似,内置了许多标准 LINQ 功能。

      我想不出一个有趣的动态 LINQ 漏洞利用,但如果这是我,我会至少成为白名单成员(OrderID,@987654323 @等)-但我可能会直接编写Expression逻辑;如果您只支持直接属性,这并不是特别难。

      例如,这里是Where(使用您的Contains 逻辑):

      static IQueryable<T> Where<T>(this IQueryable<T> source,
          string member, string value)
      {
          var param = Expression.Parameter(typeof(T), "x");
          var arg = Expression.Constant(value, typeof(string));
          var prop = Expression.PropertyOrField(param, member);
          MethodInfo method = typeof(string).GetMethod(
              "Contains", new[] { typeof(string) });
          var invoke = Expression.Call(prop, method, arg);
          var lambda = Expression.Lambda<Func<T, bool>>(invoke, param);
      
          return source.Where(lambda);
      }
      

      我已经报道了OrderBypreviously, here

      【讨论】:

        猜你喜欢
        • 2013-09-29
        • 2020-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-20
        • 2015-03-08
        • 1970-01-01
        • 2011-06-28
        相关资源
        最近更新 更多