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


33

リソースベースのサイト(MVCアプリケーションやRESTサービスなど)で作業する場合、クライアントGETがアクセスできないリソースをクライアントが試行する場合、主に2つのオプションがあります。

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

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

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

プライバシーの観点からは、どのリソース誰かが伝えを見て、リアリティショー(サバイバーが、私は思う)の受賞者を出した前記私は事件を思い出してる404を返すように多くの方が安全と思われるしなかっ上に存在しますサイトvs. 403がシリアル番号やアカウント番号などの機密情報を提供する可能性があることを心配しています。

404を返さない説得力のある理由はありますか?404ポリシーは他の場所でマイナスの副作用を引き起こす可能性がありますか?そうでない場合、その慣行はより一般的ではないのはなぜですか?


1
404を返さない説得力のある理由:サービスがダウンしている場合、または認証にバグ/エラーがある場合、404が表示されますが、問題を診断しようとしている顧客/ユーザー/テスター/開発者/サポート担当者にはわからないことがありますエラーメッセージの何が問題なのか。
スティーブンエバーズ

@Snorfus:それは良い点です-私は答えにそれを入れていただろう。ジョシュはすでに良い対比を追加しましたが
...-アーロンノート

留意すべきもう1つの側面は、次のとおりです。404は下流でどのように扱われますか?CDNまたは何らかのキャッシュがありますか?それらをキャッシュできるようにしたい場合は、「ユーザーに権限がない」404をキャッシュしたくないでしょう。
pc1oad1etter

回答:


15

に関連する一般的な誤解(および誤用)が403 Forbiddenあります。サーバーがリクエストについてどのように考えているかについて何も伝えないことになっています。具体的に言うと、

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

UAまたはクライアントそれを解釈して、リクエストが機能しないことを意味し、適切に応答する必要があります。

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

403対照的であり401 Authorization Requiredないサーバは限り、あなたは正しい資格情報を渡すようとして要求を処理することを離れて与えます。これは通常、人が聞い403たときに考えることです。

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

とを使用する401404、サーバーはクライアントまたはUAに処理方法について何も伝えません。別の応答が得られることを期待して試行を続けることができます。

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

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

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

そのため、ステータスコードは悪意のあるユースケース用ではなく、ルールに従ってプレイしているクライアント用です。そして、それらのクライアントにとって401404リクエストは最も適切です。


4
401と403についての良い点。しかし、404に関するあなたの声明の最終性には同意しません。確かに、Facebookの例では、あなたはすでにそれquuxが存在することを知っています。しかし、特にクライアントデータが本当にプライベートである非ソーシャルサイトでは、外部の証拠が常にあるとは限りません。おせっかいまたは敵対的使用者は、最終的に推定することができるかもしれないことを必ずしもあなたが嘘をついているが、これはあなたが横たわっているリソースについて。ここでの重要なポイントは本当に、他の利用可能な発見方法がない限り、404リソースを気にしない
アーロンノート

@Aaronaught重要なのは、サーバーがだまされていることを誰かが把握できないこと、または強化されていない発見の方法がないことを、本当に、本当に確信しなければならないということです。賢い人それ理解し、その時点で、ステータスコードは無意味です。

1
ユーザープロファイル間でデータが共有されていない場合に、十分に賢い人どのようにそれを把握できるかについては、まだわかりません。私は、誰かが最終的に「ああ、404は実際に存在する可能性があることを意味するが、私はそれにアクセスできない」ことを理解することを理解しています-しかし、サーバーが本当に存在しないリソースに対して同じエラーを返すと仮定すると、どのようになりますか?存在しないリソースと特権リソースの違いを教えてください。
アーロンノート

@Aaronaught人が知る必要があるのは、プロファイルへのURLが存在することだけです。プロファイルIDを使用して擬似的にインクリメントするだけです(したがって、プロファイルIDが3333の人はプロファイルIDが3332の人がいるわけではありません)が、決まった人はそれを予測できるはずです有効なIDのサンプルサイズ。それに失敗し、プロファイルページのURLを生成する方法に関する情報を一切漏らさない完全に強化されたシステムを考えると、常にソーシャルエンジニアリングがあります。

8

RFC2616によると

10.4.4 403禁止

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

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


RFCは現実にほとんど似ていませんが、RFCを知っています。ほとんどのサーバは、これまでその最初の文を超えた403の理由を説明していない(「サーバーが要求を理解したが、それを実行することを拒否している。」)と、ほとんどのMVCフレームワークがさえに似何か持っているHttpUnauthorizedResult特権リソースのために使用されることが意図されています。また、(明らかに)404 代わりに使用できることにも気付きました。私の質問は、それ使用すべきかどうか、そしてその決定を下すときに考慮すべきことです。
アーロンノート

@Aaronaught:RFCは404の使用を許可するだけでなく、何も確認したくない場合に404​​をスローすることを推奨しています。
ライライアン

3
それは問題ありませんが、いつ私は何も認めるべきではありませんか?むしろ、いつ私はすべきですか?それが本当に質問の本質です。
アーロンノート

5

あなたは?はい

あなたはそれを自分で言って、できるだけ裏切りません。システムを攻撃していて、サーバーが403コードで応答したことに気付いた場合、先に進むのではなく、それらに焦点を合わせます。ドアが存在しないことを宣言してから、禁止することを宣言することをお勧めします。

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

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


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

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

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

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

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

有効なリクエストではなく、不正なリクエストです。小さな部分を変更して(403の代わりに404を返す)、攻撃者になりそうな場合に実質的な利点を得ます。


あいまいさによるセキュリティ...本当に?誰かがあなたのサービスを悪意を持って突こうとしている場合、彼らはそれがそこにあることをすでに知っています。一方、「404」を取得する有効なリクエストは、必要のない場所に複雑さとあいまいさを追加するだけです。
スティーブンエバーズ

4
@Snorfus:ここでセキュリティプライバシーの間には微妙な区別があります。プライバシーは、ほぼ定義上、「あいまいさによる」ものです。リソースの存在または非存在は潜在的に重要な情報であるため、これはリソースベースのシステムのコンテキストでは特に重要です。セキュリティの議論もあるかもしれませんが、私はそれらにあまり関心がありません。私は考え、この追加の複雑さについての詳細を聞きたいです。最初のコメントを超えて詳細に進むことができますか?(おそらくより包括的な答えですか?404'ed 403に噛まれたことがありますか?)
アーロンノート

2
@Snorfus:後付けとして、徹底的な防御はセキュリティによる隠蔽とは異なります。後者は、の保護手段がないことを意味します。しかし、すでにセキュリティで保護されたシステムに不明瞭さを追加することは、将来的に他の問題を引き起こさない限り、しばしば良いことです。この場合、404が認証コードによって発行されているため、システムがすでにセキュリティで保護されていることが前提となります。
アーロンノート

@Aaronaught:より詳細な回答を投稿しますが、問題は次のとおりです。リソースがプライベートである場合、それを公開する理由は何ですか?
スティーブンエバーズ

@Snorfus:リソースは、世界全体ではなく、クライアント(またはグループ)にプライベートです。
アーロンノート

0

403ステータスコードによって提供される情報に大きく依存します。に応答するAPIエンドポイントがある場合GET /myresource/{id}リソースが存在しないときに404でポイントがある場合、リソースは存在するが現在のユーザーに許可されていないときにエンドポイントから返されるステータスコードは、idパラメーターの予測可能性と、それ自体に含まれる情報の。

  • もし id電子メールアドレスや銀行口座番号などのプライベートフィールドの、おそらく常に404の後ろに隠しておく必要があります。
  • もし idが公開ユーザー名であるは、気にしないでください。この情報にアクセスする他の方法があります(Webサイトのフォーラムページを参照するなど)。
  • もし id、不透明な、しかし、予測可能な識別子(例えば、自動インクリメントの整数)である、あなたは彼が他の手段によって得ることができなかったことを攻撃者に任意の情報を離れて与えることはありません。したがって、私の意見では、403ステータスコードを返すのは安全です。
  • 場合id(ランダムGUIDのような)不透明、予測不可能な識別子であり、問題はもっと微妙です。個人的には、403ステータスコードを返すことに問題はないと思います。このIDを使用しているAPIに別の欠陥のあるエンドポイントがある場合にのみ、この情報を利用できますが、本当の欠陥は他のエンドポイントです。

どんな場合でも、後悔するよりも安全であることが前提であり、コンテキストに関係なく情報を非表示にすることができますが、実際には、このタイプの動作に依存して何らかのセキュリティを提供することはできません。一方、それは提供することができます機密性(または他の人が言ったようにプライバシー)を。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.