5

カレンダーのような ASP.NET MVC アプリケーションがあります。NerdDinner の例に従って、UpdateMethod() を使用して編集ページの結果を更新しています。

私のアプリでは、特定のイベントは完全にカスタマイズ可能で、特定のイベントは部分的にしかカスタマイズできません。部分的にカスタマイズ可能なイベントを編集するための編集フォームにはこれらのフィールドしかありませんが、誰かが不足しているデータを使用して独自のフォームを作成し、私のサイトに投稿する可能性があります。そうする場合、誰かが一部/すべてのフィールドを変更できないようにするにはどうすればよいですか? さらに悪いことに、ID (主キー) を変更しようとした場合はどうなるでしょうか?

UpdateModel() は非常に基本的なハッキングに対して脆弱であるように感じます。私の恐れは正当なものですか、それとも私が見逃しているものがありますか?

// POST: /MyEvents/Edit/2
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection formValues)
{
    MyEvent myevent = eventRepository.GetMyEvent(id);

    try
    {
        UpdateModel(myevent);
        eventRepository.Save();
        return RedirectToAction("Details", new { id = myevent.MyEventId });
    }
    catch
    {
        ModelState.AddRuleViolations(myevent.GetRuleViolations());
        return View(new MyEventFormViewModel(myevent));
    }
}
4

5 に答える 5

9

「モデル バインディング セキュリティ」のセクションがありません。ユーザー入力メソッドのいずれかで更新できるプロパティのホワイトリストを常に含める必要があります。

たとえば、NerdDinner から:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create( [Bind(Include="Title, Address")] Dinner dinner)
{

}

または、UpdateModel を呼び出している場合は、許可されたプロパティの文字列配列を作成して、

UpdateModel(myObject, allowedProperties);

クラス自体をロックダウンして、特定のプロパティのみを更新できるようにすることもできます。

[Bind(Include="MyProp1,MyProp2,MyProp3")]
public partial class MyEntity { }
于 2009-10-01T20:00:58.057 に答える
4

進取の気性に富んだ人や悪意のある人が、モデルの任意のプロパティにフィールドをマッピングする可能性は十分にあります。これにはいくつかの方法があります

最も簡単な方法は、前述のように、UpdateModel のプロパティ オーバーロードを除外/含めることです。これの欠点は、メソッドが文字列配列のみを受け入れることです。これは、名前の変更を行うと、コードが同期しなくなることを意味する場合があります。

もう 1 つの方法は、バインドされたフィールドを保持する単純な DTO を使用することです。その後、DTO を取得して、イベント オブジェクトで必要なことを行うことができます。これにより、明らかに別のクラスが追加され、より手動になりますが、より多くの制御が可能になります。

public ActionResult(int id, EditForm form) {
    MyEvent event = _eventRepository.GetMyEvent(id);
    event.Name = form.Name; //etc;
    if (User.IsInRole("Organiser")) {
        event.Date = form.Date;
    }
    return ...
}

もう 1 つの方法は、必要なフィールドのみをバインドする MyEvent クラスの顧客モデル バインダーを使用することです。

于 2009-10-01T20:09:30.177 に答える