3

So I'm writing a handler that filters a cached DataTable based on the AppRelativeCurrentExecutionFilePath using the DataView RowFilter property. What's the best way to encode the input to prevent an injection attack?

Is the following sufficient? Is there a better/more-elegant way?

dataView.RowFilter = String.Format("Name LIKE '{0}%'", EncodeString(query));

private string EncodeString(string s)
{
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.Length; i++)
    {
        char c = s[i];
        if (c == '*' || c == '%' || c == '[' || c == ']')
            sb.Append("[").Append(c).Append("]");
        else if (c == '\'')
            sb.Append("''");
        else
            sb.Append(c);
    }

    return sb.ToString();
}
MyItchyChin
  • 13,733
  • 1
  • 24
  • 44
  • i don't think you can inject sql here...only cause an exception. But, yes that is pretty much exactly what I do. – dotjoe Aug 12 '09 at 14:12
  • If you're using in-memory data, why use `DataTable` and not just any collection? You'd be able to filter it with `Where` and just not bother about injections. – Sergei Rogovtcev Aug 16 '12 at 20:10
  • @SergRogovtsev - I asked the question in '09 so it was probably a .NET 1.1 app. Enterprises are slow to upgrade. – MyItchyChin Aug 20 '12 at 17:32

1 Answers1

0

You cannot inject sql in a RowFilter.

Edit: As pointed out, it is possible to get all rows in the table by injection, could something like the following work:

dataTable.AsEnumerable()
    .Where(r => r.Field<string>("StringColumn").Contains(userInput))
    .ToList().ForEach(r => Console.WriteLine(r.Field<string>("StringColumn")));
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
  • RowFilter is a string very similar to a SQL Where clause and it is exploitable via injection if you are constructing the filter string from user input. In my example I am filtering a DataTable based on the the URL (e.g http://site/handler/stringUsedInFilter) and the filter is a LIKE comparison thus anything after "handler/" needs to be sanitized otherwise something like "%25%25%25%25%25" would bypass minimum length and empty string checks to return the entire table contents. "'" would cause the filter to be invalid and throw an exception. etc... – MyItchyChin Aug 12 '09 at 14:50
  • Yes in order to not return the full table you would have to guard. Is there ever a case where the entire table is returned or is that something you can guard against? – Yuriy Faktorovich Aug 12 '09 at 15:06
  • @Yuriy : What if the input they're looking to filter on really is %%%%%? That wouldn't do them much good. What if the input is O'Brien? That would cause an SyntaxErrorException to be thrown. The input needs to be filtered. – MyItchyChin Aug 12 '09 at 16:06
  • Time to create a parameterized control inheriting from DataView? – Yuriy Faktorovich Aug 12 '09 at 17:22