Any risks with dynamic LINQ with direct user input?

c# dynamic-linq linq sql-injection

Question

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

1
10
3/7/2009 12:03:01 PM

Expert Answer

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.

8
1/13/2009 11:52:15 AM

Popular Answer

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



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow