ASP.NET MVCアプリケーションに、AJAXを使用して並べ替え可能(サーバー側)およびフィルター可能にしたいテーブルがあります。他の場所でかなり使いやすくしたいと思っていて、並べ替えとフィルター処理をクエリ式にハードコーディングする気にならなかったので、式を動的に構築する方法を探しました。これを行う最良の方法は、動的LINQでした。
以下のようなURLからのユーザー入力は、動的なWhereまたはOrderByに直接挿入されます。
/Orders?sortby=OrderID&order=desc&CustomerName=Microsoft
これにより、2つの式が生成されます。
OrderBy("OrderID descending")
Where(@"CustomerName.Contains(""Microsoft"")")
データベースに直接スローされず、ここに直接SQLを挿入することは、プロパティに反映できず、タイプセーフであり、すべてであるので機能しないことを理解していますが、私よりクリエイティブな人がいるのではないかと思います関係なくそれを悪用する方法を見つけることができます。私が考えることができる1つのエクスプロイトは、テーブルに表示されないプロパティを並べ替え/フィルター処理することが可能であるということですが、これはまだ表示されず、ハッシュによって防ぐことができるため、それほど害はありません。
直接のユーザー入力を許可する唯一の方法は、OrderByとWhereを使用することです。
確認してください、ありがとう:)
考えただけですが、ADO.NETデータサービスを見たことはありますか?これにより、上記のようなREST対応APIが提供され、多くの標準LINQ機能が組み込まれています。
私は頭のてっぺんの興味深い動的LINQエクスプロイトを考えることはできませんが、これが私であれば、少なくともホワイトリストメンバー( OrderID
、 CustomerName
など)になります-しかし、おそらく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
について説明しました 。
LINQ to SQLはタイプセーフなデータモデルクラスを使用するため、デフォルトでSQLインジェクション攻撃から保護されます。 LINQ to SQLは、基になるデータ型に基づいて値を自動的にエンコードします。
(c)ScottGu
ただし、そこでも「ゼロ除算」を取得できるため、予期しない例外をすべて処理し、有効なエントリの長さを制限することをお勧めします。JIC