views:

594

answers:

1

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();
}
A: 

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
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...
CptSkippy
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
@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.
CptSkippy
Time to create a parameterized control inheriting from DataView?
Yuriy Faktorovich