web-dev-qa-db-ja.com

開発者は、ルート変数と競合するフォームPOST変数をどのように処理する必要がありますか?

ASP.NET MVCで、/controller/action/UserIDへのHTTP投稿を実行すると...

対応するルートがあります/controller/action/{UserID}.。

フォームPOSTを実行すると、POSTされたデータUserIDは、ルートが最初に言っていたものをすべて上書きします。 (少なくともASP.NET MVC4ではそうです)

私にとって、これはいくつかのことを言います:

  • URLを信用しないでください... POSTされたデータは実際に起こっていることを隠す可能性があるためです。
  • ASP.NET MVCでルート変数名を推測できる人は誰でも、予期しないデータをコントローラーに入れることができます

  • ....?

質問

  • この動作は他のMVCフレームワーク(Railsなど)間で一貫していますか?
  • この種の予期しない結果を防ぐ方法は何ですか?すべてのPOSTをURLパラメータと照合する必要がありますか?
1

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)からのものであるかどうかは関係ありません。次に、それに基づいてすべての論理決定を行います。これには、初期承認と処理、ビジネスロジック-アクションが許可された場合にのみ実行されるように、すべて同じ値のオリジンを使用する必要があります。

2
SilverlightFox

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属性をモデル定義自体に追加することもできます。

0
Amin Saqi