10

ASP.NET MVC アプリケーションに、AJAX を使用して並べ替え可能 (サーバー側) およびフィルター可能にしたいテーブルがあります。他の場所でもかなり簡単に使用できるようにしたかったのですが、並べ替えとフィルター処理をクエリ式にハードコーディングするのは気が進まなかったので、式を動的に作成する方法を探しました。これを行うための最良の方法は、Dynamic LINQ を使用することでした。 .

以下のような URL からのユーザー入力は、動的 Where または OrderBy に直接挿入されます。

/Orders?sortby=OrderID&order=desc&CustomerName=Microsoft

これにより、次の 2 つの式が生成されます。

OrderBy("OrderID descending")
Where(@"CustomerName.Contains(""Microsoft"")")

データベースに直接スローされず、ここに直接SQLを挿入してもプロパティに反映できず、タイプセーフであるため機能しないことは理解していますが、私よりクリエイティブな人がいるのだろうか関係なく、それを悪用する方法を見つけることができます。私が考えることができる 1 つのエクスプロイトは、テーブルに表示されていないプロパティを並べ替え/フィルター処理できることですが、それでも表示されず、ハッシュによって防止できるため、これはそれほど有害ではありません。

ユーザーが直接入力できる唯一の方法は、OrderBy と Where を使用することです。

確認するだけです、ありがとう:)

4

3 に答える 3

10

LINQ to SQL はタイプ セーフなデータ モデル クラスを使用するため、既定で SQL インジェクション攻撃から保護されます。LINQ to SQL は、基になるデータ型に基づいて値を自動的にエンコードします。
(c) スコットグー

ただし、それでも「ゼロ除算」を取得できるため、予期しない例外をすべて処理し、有効なエントリの長さを制限することをお勧めします。JIC

于 2009-01-13T11:46:08.163 に答える
9

うーん... Dynamic Linq で考えられる問題が少なくとも 1 つ見つかりました。このスニペットを 1000 回実行し、CPU とメモリの消費量が増加するのを監視します (サービス拒否攻撃の簡単な方法を作成します)。

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

私はそれについてブログ記事を書きました。

于 2009-01-13T13:08:37.217 に答える
8

ちょっと考えただけですが、ADO.NET Data Services を見たことがありますか? これにより、多くの標準的な LINQ 機能が組み込まれた上記のような REST 対応 API が提供されます。

頭のてっぺんに関心のある動的 LINQ エクスプロイトを思いつくことはできませんが、これが私だったら、少なくともメンバー ( OrderIDCustomerName、など) をホワイトリストに登録しますが、おそらく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 以前にここでカバーしました。

于 2009-01-13T11:39:33.760 に答える