Latest Replies
Tuesday
Jan132009

Vulnerability of the Dynamic Linq

I while ago I've mentioned Dynamic LINQ as an interesting approach for building Linq queries from the string. Well, it turns out that it has at least one vulnerability that does not allow to use it in the production scenarios right away.

Denial of service


Let's say we execute this small snippet 100 times:

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

On my QuadCore machine this ate 24 seconds of the processor time with 200 Mb of memory being consumed by the process at max.

That has happened because string.Format does not care about the limitations of the width specifiers in the options, while formatting the output. As a result you can allocate string that is large enough to make your server feel it.

Imagine what would happen, if 10000 requests like this would be sent to the server.

Unexpected exceptions


This one is simple. Just feed the following strings to the parser in order to get DivideByZeroException or FormatException:

"0 = 0/0"
"0 = Convert.ToInt32(\"A\")"

Unless handled with the generic catch block (presence of which usually makes me feel uncomfortable about the code), these exceptions will bubble up to the user in form of another "Unexpected error has occurred. We are sorry for any inconvenience" type of screen.

How to prevent these exploits?


Here are some options:

  • remove typeof(string) from the predefinedTypes collection in the DynamicLinq implementation (this one has to be tested for the side effects, though);
  • explicitly sanitize your input parameters for "string.Format" (for example, you can run some validation rules before letting the input in);
  • start signing all your query urls on the server-side with session key to prevent any modifications;
  • handle all exceptions thoroughly (for example, by sending all calls to query parsing methods through an exception handling action policy).

There could be more ways to inject the Dynamic Linq with the undesired code, by the way. So here's the most secure option:

  • forget about using Dynamic Linq at all.
« Why is Enforce.Argument Named Like This? | Main | How to Find Extension Methods Targeting Object? »

References (2)

References allow you to track sources for this article, as well as articles that were written in response to this article.