ASP.NET MVCで、/controller/action/UserID
へのHTTP投稿を実行すると...
対応するルートがあります/controller/action/{UserID}
.。
フォームPOSTを実行すると、POSTされたデータUserID
は、ルートが最初に言っていたものをすべて上書きします。 (少なくともASP.NET MVC4ではそうです)
私にとって、これはいくつかのことを言います:
ASP.NET MVCでルート変数名を推測できる人は誰でも、予期しないデータをコントローラーに入れることができます
....?
質問
URLを信用しないでください... POSTされたデータは実際に起こっていることを隠す可能性があるためです。
URLはクライアント側の値として扱われるべきであり、とにかく信頼されるべきではありません。誰でも簡単にURLを変更でき、任意のUserID
にPOSTを簡単に作成できます。
ASP.NET MVCでルート変数名を推測できる人は誰でも、予期しないデータをコントローラーに入れることができます
これは、パラメータの改ざんによってとにかく発生する可能性があります。このガイドにはいくつかの便利なポインタがあります: http://msdn.Microsoft.com/en-us/magazine/hh580736.aspx
具体的には
それは何ですか?パラメータの改ざんは、アプリケーションの期待される機能を変更するためにパラメータが変更される攻撃です。パラメータは、フォーム、クエリ文字列、Cookie、データベースなどにあります。 Webベースのパラメータを含む攻撃について説明します。
それはどのように悪用されますか?攻撃者はパラメータを変更して、アプリケーションをだまして意図しないアクションを実行させます。クエリ文字列からユーザーIDを読み取って、ユーザーのレコードを保存するとします。これは安全ですか?いいえ。攻撃者はアプリケーションのURLを改ざんする可能性があります
MVCでは、これはモデルバインディングを介して発生する可能性があります。
モデルバインディングはModel-View-Controller(MVC)の優れた機能であり、Orderオブジェクトのプロパティが自動的に入力され、フォーム情報に基づいて定義されたタイプに変換されるため、パラメーターチェックに役立ちます。 ...入力を許可するプロパティを制限するように注意してください。また、重要なアイテムのページデータを信頼しないでください。 .。
ここで[Bind(Exclude)]属性を使用して、モデルにバインドするMVCを制限し、信頼するものとしないものを制御していることに注意してください。これにより、UserIdがフォームデータから取得されないため、改ざんされることがなくなります。
したがって、ビューに存在しないフォームパラメータが、悪意のあるユーザーによって改ざんされたり追加されたりしないように注意する必要があります。これを行うには、Exclude
属性を追加します。
public ActionResult Edit([Bind(Exclude="UserId")] Order order)
この動作は他のMVCフレームワーク(Railsなど)間で一貫していますか?
確かではありませんが、POSTとGETで権限チェックを行う必要があるため、欠陥とは見なされません。アプリケーションは、POSTされたURLがこれを行う権限を持っていると想定してはなりません。これは、フォームがオンになっているURLが最初にロードされている必要があるという誤ったアサーションのためです。
この種の予期しない結果を防ぐ方法は何ですか?すべてのPOSTをURLパラメータと照合する必要がありますか?
コードは、ルート変数またはPOST変数(MVCからUserID
という名前のメソッド変数として提供されている場合)のいずれかを取ることを決定する必要があります。それを使用しないのはなぜですか。 POSTデータまたは一貫性がある限りURL)からのものであるかどうかは関係ありません。次に、それに基づいてすべての論理決定を行います。これには、初期承認と処理、ビジネスロジック-アクションが許可された場合にのみ実行されるように、すべて同じ値のオリジンを使用する必要があります。
GET/POSTアクションを分離または区別する場合は、AcceptVerbs
属性を使用する必要があります。たとえば、アクションにPOSTリクエストのみに応答するように強制するには、次の属性を追加します。
[AcceptVerbs(HttpVerbs.Post)]
また、GETに以下を追加します
[AcceptVerbs(HttpVerbs.Get)]
これを行うことにより、望ましいリクエストタイプ(GET、POST、...)のみがアクションメソッドにアクセスできるようにすることができます。
質問の反対側については、Over Posting
と呼ばれるすべてのMVCフレームワークに関連するWeb攻撃があり、モデルバインダーに完全に依存している場合に発生する可能性があります。この攻撃を防ぐには、次の2つの方法があります。
Bind
属性の使用最初のものは明らかだと思います。そして2番目については、次のようなPOSTアクションメソッドを強化できます。
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult AddComment([Bind(Include = "Name, Email, CommentText")] Comment model)
さらに、Bind
属性をモデル定義自体に追加することもできます。