ログインリクエスト検証トークンの問題 質問する

ログインリクエスト検証トークンの問題 質問する

開発プロジェクトのエラー ログを調べていたところ、次のエラーを発見しました ( 罪のない を保護するために名前は変更されています)。

提供された偽造防止トークンはユーザー「」用ですが、現在のユーザーは「admin」です。

これは再現するのが特に難しい問題ではありませんでした。

  1. ログインページでアプリケーションを開く
  2. 2つ目のウィンドウまたはタブを開きます同じブラウザ同じコンピュータログインする前にログインページへ
  3. 最初のウィンドウでログインします(または2番目のウィンドウでログインします。順序は関係ありません)。
  4. 残りのログインウィンドウでログインを試みる

スタックトレースは-

System.Web.Mvc.HttpAntiForgeryException (0x80004005): 提供された偽造防止トークンはユーザー "" 用ですが、現在のユーザーは "admin" です。 System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext、IIdentity identity、AntiForgeryToken sessionToken、AntiForgeryToken fieldToken)、System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext)、System.Web.Helpers.AntiForgery.Validate()、System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)、System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext、IList`1 フィルター、ActionDescriptor actionDescriptor)、System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__1e(AsyncCallback asyncCallback、Object asyncState) で

ログインメソッドのシグネチャは次のとおりです。

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}

これは、インターネットの「ASP.NET MVC 4 Web アプリケーション」テンプレート プロジェクトのメソッドのシグネチャとまったく同じです。これは、Microsoft が ValidateAntiForgeryToken が必要/ベスト プラクティスであると判断したか、または他のすべての場所で使用されていたため、単にここに属性を追加したかのいずれかを示しています。

明らかに、この問題に対処するために私ができることは何もありません内でこのメソッドに到達しない場合、ValidateAntiForgeryToken は事前リクエスト フィルターであり、リクエストがコントローラーに到達する前にブロックされます。

フォームを送信する前にユーザーが Ajax 経由で認証されているかどうかを確認し、認証されている場合はリダイレクトを試みるか、単に属性を削除することができます。

質問はこれです - トークンは、ユーザーが別のサイトからのリクエスト(CSRF)を防ぐために設計されていると理解していますあなたのサイトに対してすでに認証されていますそれを根拠に定義上、認証されていないユーザーが使用するフォームから削除することは問題でしょうか??

おそらく、このインスタンスの属性は、悪意のあるユーザーがアプリケーションに偽のログイン フォームを提供することを軽減するように設計されています (ただし、例外がスローされる時点では、ユーザーは既に自分の詳細を入力しており、それが記録されていると思われますが、何かが間違っていることを警告する可能性があります)。そうでない場合、外部サイトからフォームに誤った資格情報を送信すると、サイト自体とまったく同じ結果になるのではないでしょうか。潜在的に危険な入力をクリーンアップするために、クライアント検証/サニテーションに依存していません。

他の開発者もこの問題に遭遇したことがありますか (または、非常に創造的なユーザーがいるのでしょうか)。もしそうなら、どのように解決/軽減しましたか?

アップデート:この問題は MVC5 でも依然として存在しており、完全に意図的に、既定のテンプレートと ID プロバイダーを使用すると、「提供された偽造防止トークンは、現在のユーザーとは異なるクレーム ベースのユーザーを対象としています。」というエラー メッセージが表示されます。Microsoft Developer Evangelist であり Troy の同僚である PluralSight の著者 Adam Tuliper による関連する質問と興味深い回答が次のサイトに掲載されています。ログインページの偽造防止トークントークンを単に削除することを推奨します。

ベストアンサー1

このパターンをテストしたところアサファウェブ同じ結果になります(同じデフォルト実装を使用します)。これが起こっていると私が考えることです

  1. どちらのログイン フォームも、同じ __RequestVerificationToken クッキー (同じ DOM に設定されている同じクッキー) と同じ __RequestVerificationToken 隠しフィールドを使用して読み込まれます。これらのトークンは匿名ユーザーにキー設定されます。
  2. ログインフォームAは上記のトークンを送信し、検証して、ブラウザDOMにある認証クッキーを返します。
  3. ログインフォームBの投稿また上記のトークンでは今では、ログイン フォーム A から設定された認証 Cookie も投稿されます。

問題は、トークンが匿名ユーザーにキー設定されているにもかかわらず、認証されたユーザーによってリクエストに渡されているため、ステップ 3 でトークンが検証されないことです。これが、エラーが表示される理由です。提供された偽造防止トークンはユーザー「」用ですが、現在のユーザーは「admin」です

この問題は、フォーム B がフォーム A が投稿される前に読み込まれ、フォーム B が匿名ユーザーによって投稿されることを予期しているために発生します。

定義上、認証されていないユーザーが使用するフォームから削除することは問題になりますか?

偽造防止トークンが防御する主な根本的なリスクはCSRFであり、いつもの認証されたユーザーを利用するのは、ブラウザーがだまされて発行されるリクエストにはすべて認証 Cookie が付随するため、ユーザーに代わってアクションが実行されるからです。このリスクはログイン フォームには存在しません。通常、ユーザーは認証されておらず、ここでの最悪の CSRF ケースはログインが偽造されて失敗することです。ユーザーに代わって送金しているわけではありません。

ただし、偽造防止トークンには他の利点もあります。たとえば、メソッドを実際に実行して DB を攻撃するブルート フォース攻撃を防止できます。これについて心配するよりも、質問で遭遇しているシナリオについて心配するかどうかを決める必要があります。そうでない場合、偽造防止検証が行われる前に、リクエスト パイプラインのどこかにドロップ ダウンして、リクエストに認証 Cookie がすでに存在する場合はアクションを実行する必要があります。

率直に言って、私は問題がよくわかりません。この問題を再現するには、ユーザーは複数のログイン フォームを同時に開いて、それぞれに連続してログインする必要があります。これは本当に心配するほど頻繁に発生するのでしょうか。また、実際に発生した場合、2 回目のログインでカスタム エラー ページが返されることは本当に問題でしょうか (もちろん、本番環境ではそうします)。私の意見では、デフォルトの動作のままにしておきます。

おすすめ記事