直接用户输入的动态 LINQ 有什么危险吗?

发布于 2024-07-11 21:24:45 字数 632 浏览 7 评论 0原文

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

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

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

这将导致两个表达式:

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

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

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

只是确认一下,谢谢:)

I have a table in a ASP.NET MVC application that I want to be sortable (serverside) and filterable using AJAX. I wanted it to be fairly easy to use in other places and didn't feel like hardcoding the sorting and filtering into query expressions so I looked for a way to build the expressions dynamically and the best way to do this I found was with Dynamic LINQ.

User input from a URL like below is directly inserted into a dynamic Where or OrderBy.

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

This would result in two expressions:

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

While I understand that it won't be thrown at the database directly and inserting straight SQL in here won't work because it can't be reflected to a property and it's type-safe and all, I wonder if someone more creative than me could find a way to exploit it regardless. One exploit that I can think of is that it's possible to sort/filter on properties that are not visible in the table, but this isn't that harmful since they still wouldn't be shown and it can be prevented by hashing.

The only way I allow direct user input is with OrderBy and Where.

Just making sure, thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

悟红尘 2024-07-18 21:24:45

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

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

Because LINQ to SQL uses type-safe data model classes, you are protected from SQL Injection attacks by default. LINQ to SQL will automatically encode the values based on the underlying data type.
(c) ScottGu

But you can still get "divide by zero" there, so it is recommended to handle all unexpected exceptions and also limit length of the valid entries, JIC

演出会有结束 2024-07-18 21:24:45

嗯...我刚刚发现 Dynamic Linq 至少存在一个可能的问题。 只需执行此代码片段 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));

我写了一个 博客文章 对此。

Hum... I've just found at least one possible issue with the Dynamic Linq. Just exec this snippet 1000 times and watch for the CPU and memory consumption going high up (creating an easy way for the denial of service attack):

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));

I wrote a blog post on that.

白龙吟 2024-07-18 21:24:45

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

我想不出有什么有趣的动态 LINQ 漏洞利用,但如果这是我的话,我会至少白名单成员(OrderIDCustomerName等) - 但我可能会直接编写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);
}

我已经介绍了 OrderBy 之前,此处

Just a thought, but have you looked at ADO.NET Data Services? This provides a REST-enabled API much like the above with a lot of standard LINQ functionality built in.

I can't think of an interest dynamic LINQ exploit of the top of my head, but if this was me I'd be at least white-listing members (OrderID, CustomerName, etc) - but I'd probably write the Expression logic directly; it isn't especially hard if you are only supporting direct properties.

For example, here is Where (using your Contains logic):

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);
}

I've covered OrderBy previously, here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文