web-dev-qa-db-ja.com

MVC / RESTは、他のユーザーに属するリソースに対して403または404を返す必要がありますか?

リソースベースのサイト(MVCアプリケーションやRESTサービスなど)を操作する場合、クライアントがリソースをGETしようとすると、2つの主要なオプションがありますtにアクセスできます:

  • 4、これはクライアントがunauthorized;であることを示します。または
  • 404は、リソースが存在しない(または見つからなかった)ことを示します。

一般的な知恵と一般的な実践は、真実、つまり403で応答するようです。しかし、これが実際に正しいことなのかどうか疑問に思っています。

安全なログインシステムは、ログイン失敗の理由を決して教えません。つまり、クライアントに関する限り、存在しないユーザー名と不正なパスワードの間に検出可能な違いはありません。これの目的は、ユーザーID(さらに悪いことに、電子メールアドレス)を発見可能にしないことです。

プライバシーの観点からすると、404を返す方がはるかに安全だと思われます。誰かが現実の勝者を見つけたと報告された事件を思い出しますサイトに存在するリソースが存在しなかったかどうかを調べて(生存者だと思います)表示します。 403がシリアル番号や口座番号などの機密情報を潜在的に提供することを懸念しています。

404を返さなければならないわけがない理由はありますか? 404ポリシーは他の場所で負の副作用を持つことができますか?そうでない場合、なぜ慣行がより一般的ではないのですか?

34
Aaronaught

403 Forbiddenに関連する一般的な誤解(および誤用)があります。サーバーが要求について何を考えているかについては何も提供することは想定されていません。それは特に言うように設計されています、

私はあなたが要求しているものを手に入れますが、あなたが何をしようとしても、私はその要求を処理しません。だからやめよう。

すべてのUAまたはクライアントshouldは、要求がnever機能し、適切に応答することを意味すると解釈します。

これは、ユーザーに代わってリクエストを処理するクライアントに影響を与えます。ユーザーがログインしていない場合、またはタイプミスした場合、リクエストを処理するクライアントは、「申し訳ありませんが、何もできません」と最初に返信します。 403を取得し、今後のリクエストの処理を停止します。明らかに、障害が発生した後もユーザーが自分の個人情報へのアクセスを要求できるようにしたい場合、これはユーザーに敵対的な動作です。

403401 Authorization Requiredとは対照的です。これはdoesは、正しい資格情報を渡す限り、サーバーが要求を処理することを示します。これは通常、人々が403を聞いたときに考えることです。

他の人が指摘したように、「そのページが見つかりません」と言うだけでなく、サーバーが将来の成功または失敗の主張をしないことをクライアントに示唆するように設計されている404 Page Not Foundとも対照的ですリクエスト。

401404を使用すると、サーバーはクライアントやUAに対して、どのように進むべきかについて何も言わず、別の応答を得ることを期待して試行し続けることができます。

したがって、404は、全員に見せたくないページを処理する適切な方法ですが、特定の状況で表示しない理由については何も伝えたくありません。

もちろん、これはリクエストを行うクライアントがささいなRFCフリップを気にすることを前提としています。悪意のある十分なクライアントは、偶発的な方法を除いて、返されたステータスコードを気にしません。他の既知のユーザーページと比較することで、それが非表示のユーザーページ(または潜在的な非表示のユーザーページ)であることがわかります。

つまり、ハンドラがusers/*であるとしましょう。 users/foousers/barおよびusers/baazが機能していることがわかっている場合、サーバーは401に対して403404、またはusers/quuxを返します私が試してみるつもりはありません。特に、そこに信じる理由がある場合はisquuxユーザーです。標準的なシナリオ例はFacebookです。私のプロフィールは非公開ですが、公開プロフィールに対する私のコメントは非公開です。悪意のあるクライアントは、あなたが私のプロフィールページで404を返しても、私が存在することを知っています。

したがって、ステータスコードは悪意のあるユースケースではなく、ルールを実行するクライアントのためのものです。そしてthoseクライアントの場合、401または404リクエストが最も適切です。

16
user8

RFC2616 によると

10.4.4 403 Forbidden

サーバーは要求を理解しましたが、要求の実行を拒否しています。承認は役に立たず、リクエストは繰り返されるべきではありません。リクエストメソッドがHEADでなく、サーバーがリクエストが満たされていない理由を公開したい場合は、エンティティに拒否の理由を記述してください。サーバーがこの情報をクライアントに提供したくない場合は、代わりにステータスコード404(Not Found)を使用できます。

禁止されたリソースにアクセスする場合、承認は役に立たないことにも注意してください。

9
Lie Ryan

しますか? はい

あなたはそれを自分で言いました、できるだけ裏切らないでください。システムを攻撃していて、サーバーが403コードで応答していることに気付いた場合は、先に進むのではなく、それらのコードに集中します。ドアが存在しないことを宣言してから、禁止することを宣言する方が良いでしょう。

404リクエストを使用することの欠点は、外部的にはページが存在しないかのように見えることであり、存在すると想定されているが存在しないページと比較すると競合が発生する可能性があります。代わりに。 Webクローラーについて心配していない場合(認証されたシステムはとにかく完全に拒否する必要があります)、絶対にそれを行う必要があります。私が使用したすべてのAPIは、不正アクセスをまったく同じ方法で処理します StackOverflowも同様です 。そのページを見ることができませんか?私はあなたがそうではないと主張しているとしても、それが存在することを保証します.

リソースが存在することがわかっており、アクセスが拒否された場合、要求を確認する必要があります。ログインに失敗しても、404メッセージは表示されません。リソースの存在自体を保護する必要がある場合、リクエストを承認するべきではありません。レルムへのアクセスは公開されていますが、セキュリティグループまたはセキュリティグループ内のロールは公開されていません。


404を返さない説得力のある理由:サービスが停止しているか、認証にバグ/エラーがある場合、404が返されますが、問題を診断しようとしている顧客/ユーザー/テスター/開発者/サポートの担当者は何もわからない可能性がありますエラーメッセージの何が問題になっていますか

開発者はログにアクセスできる必要があります。これは、保護されたリソースへのアクセスの試みを示します。顧客/ユーザー/テスターはフィードバックを生成し、最終的には開発者を襲います。

あいまいさによるセキュリティ...本当に?

これは無名によるセキュリティではありません。適切なセキュリティ対策に加えて、あいまいさを使用しています

一方、「404」を取得する有効なリクエストは、必要がない場合に複雑さと不明瞭さを追加するだけです。

これらは有効なリクエストではなく、無許可リクエストです。小さな部分(403ではなく404を返す)を変更して、攻撃者になる可能性のある人に大きな利点をもたらします。

5
Josh K

実際には、403ステータスコードによって提供される情報によって異なります。リソースが存在しないときにGET /myresource/{id}に404で応答するAPIエンドポイントがある場合、リソースは存在するが現在のユーザーに承認されていないときにエンドポイントから返されるステータスコードは、 idパラメータ、およびそれ自体に含まれる情報の量。

  • idが電子メールアドレスや銀行口座番号などのプライベートフィールドである場合、おそらく404の後ろに隠す必要があります。電子メールアドレスの場合、スパムボットが有効な電子メールのリストをコンパイルするのを防ぐことができます。あなたのウェブサイトに登録されたアドレス。
  • idがパブリックユーザー名である場合は、気にしないでください。この情報にアクセスするには、他の方法があります(たとえば、Webサイトのフォーラムページを閲覧するなど)。
  • idが不透明だが予測可能な識別子(自動インクリメント整数など)の場合、他の方法では入手できなかった情報を攻撃者に提供することはありません。したがって、私の意見では、403ステータスコードを返すのが安全です。
  • idが不透明で予測不可能な識別子(ランダムなGUIDなど)である場合、質問はより微妙です。個人的には403ステータスコードを返却しても問題ないと思います。この情報は、このIDを使用するAPIに別の欠陥のあるエンドポイントがある場合にのみ悪用される可能性がありますが、実際の欠陥はIS他のエンドポイントです。

どんな場合でも後悔するよりも安全である方が良いと思い、コンテキストを問わず情報を隠すことができますが、実際にはこのタイプの動作に依存してsecurityの形式を提供することはできません。一方、それはconfidentiality(またはプライバシー、他の人が言ったように)を提供できます。

セキュリティメカニズムは、攻撃者にとって単なるスピードバンプであってはなりません。そうでなければ、それは単に役に立たないだけです。この場合、他の機能(クローラー、Webアプリケーションファイアウォールが異常な量の403ステータスコードを探してユーザーをブロックする...)を正しく使用できない場合さえあります。

0
Maxime Rossini