コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

認証が必要なページにおける403/401と404の使い分けに関してざっくりまとめる

認証エラーだから401を返してあげるのがよいのか、悪いのかをざっくりまとめる

TL;DR

  • 順当に作る場合は認証を終えていないと見れないページはHTTPステータスコードは403(認可における不足の場合は401)のレスポンスコードを返す
  • ただし認証をした人だけ認識できるページの場合は認証できないときのエラーのHTTPステータスコードは404とする場合もある
    • ページとして存在することを認知されたくない場合がこれに該当する

そもそもHTTPステータスコードの403/401と404とは

ざっくり表現すると404はリソースが存在しないことを示し、403/401はリソースへのアクセスを行うことができない旨を示すものとなる。

404

404 は標準的なレスポンスコードの1つで、リクエストされたリソースがサーバー上で見つからなかったことを表します。 - 404 | MDN

403

HTTP の 403 Forbidden クライアントエラーレスポンスコードは、サーバーがリクエストを理解したものの、認証が拒否されたことを示します。 - 403 Forbidden - HTTP | MDN

401

HTTP 401 Unauthorized は、有効な認証資格が不足していることによりリクエストが適用されないことを示すクライアントエラーのレスポンスコードです - 401 Unauthorized - HTTP | MDN

ログインが必要なページに未ログインでアクセスしたときの処理

要ログインのページを作っている場合、そのページにアクセスする際にログイン情報がないと閲覧不能な場合は、前提となる説明のステータスコードを鑑みた場合だと「ログイン、すなわち認証を済ませていないユーザからのアクセスのため、認証が拒否されている状態なので403」と考えることができる。そのためログインが必要なページに未ログインでアクセスすると403ページを出す、というような作りをするケースがある。

認証している人だけに知らせたいページは存在を教えない

ただし、403や401は「このページは認証をしないといけないページです」というのを明示的に表現してしまう。例えば、以下のようなURLのパターンがあるとする。

このURLにおいて、https://example.com/secret/ 配下はログインが必要なページとなっており、この中で実際に存在するページは https://example.com/secret/page/xiqaapes/ とした場合、前2つは404、最後の1つは403でレスポンスが帰ってくるとする。

この場合に、最後の xiqaapes のページだけ副次的な効果で「存在をすること」を表現してしまう。

この副次的な効果で不都合が発生する場合がある、それは悪意を持ったユーザが権限内の情報を探し当てたいときに、情報があることのヒントとなってしまうことである。

些細な情報かもしれないが、少ないヒントを掛け合わせて悪意のあるユーザは攻撃などをしかけるので、「本当に認証している人以外には存在を秘匿したほうがよい」というケースの場合はレスポンスとしても存在しない体裁にして404を返す場合がよいケースもあるので、ページのコンテキストによっては検討したほうが良い。

なお、GitHubなどが404にする方向性を取っており、アクセスする権利があれば正常に表示されるページもログアウトすると404扱いになって見れない形になっている。

参考リンク