4

私はEFコードファーストアプローチを使用してDB構造を定義しました。現在、EFエンティティクラスをMVCアプリケーションの一部のビューに直接渡しています。これにより、ビューの入力と保存が簡単になります。これは、リポジトリに入力されたEFクラスを直接提供させることができ、コントローラーがポストバックでEFエンティティクラスを受け取った場合、(検証がOKの場合)それを直接渡すことができるためです。リポジトリに保存します。ただし、これは潜在的にセキュリティリスクですか?変更したくないプロパティがエンティティクラスにある場合、クライアントはそれらのプロパティをポストバックの一部として送信し、とにかく変更できますか?たとえば、このEFモデルを渡すユーザーを編集するビューがあるとします。

public class User {
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Surname { get; set; }
    public DateTime DOB { get; set; }
    public bool IsDisabled { get; set; }
}

Firstname、、Surnameおよびを編集可能なフォームフィールドとして公開する場合がありますが、ユーザーがアカウントを設定および無効化DOBできるようにしたくありません。IsDisabledこれを防ぐための最良の方法は何ですか?おそらく、ビューでドメインモデルを直接使用する必要があるのは、そのドメインモデルによって保持されているすべてのプロパティをユーザーが設定できるのは問題ないと考える場合、またはそのドメインモデルを使用して物を表示するだけで、物を保存するのではない場合です。データストア?

4

4 に答える 4

5

はい、エンティティをビューに直接渡すのは危険な場合があります。技術的には、問題は、エンティティに直接バインドをモデル化する場合です。

はい、あなたが提示した状況が発生する可能性は非常に高いです。さらに悪いことに。Userオブジェクトをパスすると、攻撃者はpost値を送信して、IsAdminをtrueに設定したり、ユーザーに割り当てられたロールを変更したりする可能性があります。

もちろん、これはすべて、データの構造を知っている(または推測できる)ユーザーに依存します。生成されたHTMLには、ヒントを与えるわかりやすい記号が含まれていることが多いため、これは見た目ほど難しくはないかもしれません。

この問題には2つの解決策があります。

1)ビューモデルを使用します。ビューモデルには、ビューで許可されているデータのみが含まれています。また、どのデータをエンティティモデルにコピーして戻すかを制御することもできます。

2)属性を使用して、[Bind]さまざまなプロパティをホワイトリストおよびブラックリストに登録するための除外と包含を指定できます。

何かをホワイトリストまたはブラックリストに登録することを忘れるのははるかに難しいので、最初のアプローチを使用することをお勧めします(特に、後で何かを変更し、バインドするすべての場所でリストを更新するのを忘れた場合)。[Bind]また、浮気をしているような気がして、ずさんなデザインを奨励しています。

于 2012-10-14T23:57:42.887 に答える
3

エンティティモデルをビューモデルとして使用することは実際には想定されていません。ここでの例は、他のどこよりも優れていることを示していると思います。

あなたのコントローラーが投稿時にUserそれを受け入れた場合、そうです、あなたはそこに投稿されるそのデータを公開するでしょう。無効な送信をチェックせずに投稿されたユーザーを直接マッピングした場合は、問題をデータベースに永続化することになります。

于 2012-10-15T00:02:00.530 に答える
2

最善の策は、ビューモデルを使用することです。IsDisabledそうすることで、ビューモデルにまったく存在しないような、非表示のプロパティにアクセスしようとする誰かから保護され、ドメインをプレゼンテーション層から切り離すことができます。EFエンティティを拡張する必要がある場合(より多くのプロパティ、より多くの関係など)、ビューモデルを変更する必要はないでしょう。

于 2012-10-14T23:56:56.327 に答える
0

この投稿に出くわしたばかりです:http:
//www.codethinked.com/ASPNET-MVC-Think-Before-You-Bind

この問題に対処するためのいくつかのアプローチがありますが、私のプロジェクトで選択したものは、UpdateModel()アプローチの変形です。このアプローチは、DBから更新可能なオブジェクトを取得し、そのオブジェクトで更新するフィールドのみUpdateModel()を設定するために使用することに依存しています。私のアプローチは、リポジトリのメソッドが、更新するフィールドの設定を担当するラムダ(「更新戦略」)を取得することです。Update

public bool UpdateUser(User updatedUser, Action<User, User> updateStrategy) {
    // Retrieve User via updatedUser.UserID...
    // Update it using updateStrategy(retrievedUser, updatedUser)...
    // Save the updated retrievedUser to DB
}

// ...
// To call the update method:
repoUser.UpdateUser(updatedUser, (existingUser, updatedUser) => {
    existingUser.Firstname = updatedUser.Firstname;
    existingUser.Surname = updatedUser.Surname;
    existingUser.DOB = updatedUser.DOB;
});

どちらの場合も、アクションメソッドに投稿されたかどうかに関係なく、不要なフィールドが更新されないように保護します。もちろん、悪意のあるクライアントが隠しUserIDフィールドを変更する可能性はありますが、それを防ぐ必要はないと思います。更新するユーザーを変更するだけであり、システムがユーザーに許可を与えるべきではないユーザーを更新させた場合、それ自体がセキュリティ上の欠陥のように思われます。

于 2013-03-20T10:23:49.213 に答える