結論(存在しないURLのステータス)
存在しないURLのステータスとは、存在しないページへアクセスしたときにサーバーが返すHTTPステータスコードのことで、正しくは404(Not Found)または410(Gone)です。トップページへリダイレクトしたり、「ページが見つかりません」を200(OK)で返したりする状態はソフト404と呼ばれ、監視・検索エンジン・脆弱性診断・キャッシュが「存在する」と誤認する原因になります。
この記事のポイント
- 存在しない資源は404(見つからない)または410(恒久的に無くなった)で返すのが原則です(RFC 9110)。
- トップへの302や「見つかりません」画面の200はソフト404で、誤公開ファイルの発見の遅れやWeb Cache Deceptionにつながります。
- ApacheのErrorDocumentに http:// から始まる完全URLを書くとリダイレクトになり、404が失われます。
- セキュリティAIチェッカーは、ランダムな存在しないパスの最終ステータスが404・410なら○、それ以外は△と判定します。
- 利用者への親切さは、リダイレクトではなく404応答の本文に検索窓や主要リンクを置くことで実現します。
| 診断項目名 | 存在しないURLのステータス |
|---|---|
| 項目ID | response.soft-404 |
| 分類 | HTTP応答・エラー処理 |
| 重大度・配点の重み | 中(medium) 重み 2 |
| 関連する標準・ガイドライン | RFC 9110(HTTP Semantics)15.5.5 404 Not Found/15.5.11 410 Gone/OWASP ASVS 5.0.0 V14.2.5(Level 3:存在しないファイルへのアクセスには、別の有効なファイルではなく 404 または 302 を返す。Web Cache Deception 対策)/OWASP WSTG-ERRH-01(Testing for Improper Error Handling:存在しないファイル・フォルダーへのリクエスト)/Google Search Console ヘルプ「404 (Page Not Found) errors」(soft 404) |
存在しないURLのステータスとは(404・410とソフト404)
存在しないURLのステータスとは、存在しないページへアクセスしたときにサーバーが返す HTTP ステータスコードのことです。原則として、サーバーは 404(Not Found)または 410(Gone) を返します。
HTTP/1.1 404 Not Found
ところが、トップページへリダイレクトしたり、「ページが見つかりません」という文面を 200(OK)で返したりするサイトがあります。これを一般にソフト404と呼びます。ソフト404は直ちに侵入につながる脆弱性ではありませんが、監視・検索エンジン・脆弱性診断・キャッシュが「存在する」と誤認する原因になり、誤公開ファイルの発見を遅らせたり、診断結果の信頼性を下げたりします。
セキュリティAIチェッカーは、明らかに存在しないランダムなパスを1回取得し、最終的なステータスコードを確認します。
HTTP 仕様上の位置付け(RFC 9110)
| ステータス | 意味 |
|---|---|
| 404 Not Found | オリジンサーバーが対象リソースの現在の表現を見つけられない、または存在を開示したくないことを示す。ヒューリスティックにキャッシュ可能 |
| 410 Gone | 対象リソースがもはや利用できず、その状態が恒久的である可能性が高いことを示す |
| 403 Forbidden | 禁止されたリソースの存在を隠したいオリジンサーバーは、代わりに 404 で応答してよい(MAY)とされる |
存在しない資源に 403 を返す構成は仕様違反ではありませんが、「存在するが禁止」と区別できなくなります。
ソフト404はなぜ問題なのか
1. 検索エンジン
Google Search Console ヘルプの 404 エラーの解説は、存在しないページについて、偽のコンテンツを作る、ホームページへリダイレクトする、robots.txt で404をブロックするといった方法を避けるよう求め、それらはサイト構造の把握を難しくすると説明しています。ソフト404は、検索結果の品質低下や、古いURLがいつまでも残る原因になります。
2. 監視とリンク切れ検出
死活監視や CMS のリンクチェッカーは 200 を「正常」とみなすため、ページの消失や設定ミスに気付けません。
3. セキュリティ診断の精度
.env、.git/HEAD、バックアップファイルの有無を調べる診断は、存在しないパスが 200 を返すと、実在の判定に本文解析が必要になります。セキュリティAIチェッカーでも、「代表的な管理ファイルが公開されていない」や「旧版・バックアップファイルの露出」は、誤検知を避けるため本文の署名を確認しています。
4. キャッシュ(Web Cache Deception)
CDN やブラウザが「存在しないURLの200応答」を正規コンテンツとして保存し、意図しない内容が長く配信されることがあります。OWASP ASVS 5.0.0 V14.2.5 は Web Cache Deception(/mypage/x.css のような存在しないパスで動的ページを返させ、静的ファイルとして共有キャッシュに保存させる攻撃)を防ぐため、存在しないファイルには別の有効なファイルを返さないことを求めています。
同要件はキャッシュの観点から 302 も許容していますが、この診断項目は検索エンジンや監視への影響も含めて評価するため、リダイレクト先の最終ステータスで判定します。
よくある誤解
- 「存在しないURLはトップへ飛ばしたほうが親切」:利用者には何が起きたか分からず、検索エンジンにはソフト404と扱われます。親切さは、404応答の本文に検索窓や主要リンクを置くことで実現できます。
- 「カスタム404ページを作ったので大丈夫」:見た目のページは正しくても、
ErrorDocumentの指定方法やCMSの設定によっては、ステータスが 200 になっていることがあります。ブラウザ表示ではなく、ステータスコードを確認する必要があります。
存在しないURLのステータスの診断基準(セキュリティAIチェッカー)
取得方法
- 診断対象オリジンに対して
/miniparse-ver2-not-found-<タイムスタンプ>を GET で1回取得します(タイムアウト7秒、最大3回までリダイレクトを追従、本文は最大500KB)。 - リダイレクトを追従した後の最終応答のステータスコードで判定します。したがって「トップページへ302 → トップページが200」はソフト404として扱われます。
判定条件
| 判定 | 条件 | 根拠表示(例) |
|---|---|---|
| ○ 問題なし(pass) | 最終ステータスが 404 または 410 | 存在しないURLはHTTP 404でした。 |
| △ 要確認(warn) | 最終ステータスが 200(ソフト404) | 存在しないURLはHTTP 200でした。 |
| △ 要確認(warn) | 上記以外(403、400、500、503 など) | 存在しないURLはHTTP 403でした。 |
| × 要改善(fail) | この項目では使用しない | ― |
| 対象外(na) | 取得自体に失敗(接続不可、タイムアウト、リダイレクト4回以上、本文が500KB超、証明書検証エラーなど) | エラー応答を取得できませんでした。 |
- 403 や 5xx を△とするのは、存在しない資源の扱いとして意図どおりか確認が必要なためです。5xx の場合は、エラー処理の不具合や WAF・ロードバランサー設定の問題が疑われます。
- ×(fail)は使用しません。直接的な侵害ではなく、運用・検知性の問題であるためです。
得点への影響
重み2。○は2点、△は0.9点(2×0.45)、×は該当なし。対象外は分母から除外します。
自治体サイトでの判定例
| 設定・挙動 | 最終ステータス | 判定 |
|---|---|---|
Apache で ErrorDocument 404 /404.html を設定 | 404 | ○ |
ErrorDocument 404 https://www.example.lg.jp/ のように完全URLを指定(Apache がクライアントへリダイレクトを返す) | トップページの200 | △ |
| CMS の「ページが見つかりません」テンプレートを 200 で返す | 200 | △ |
| WAF が見慣れないパスに 403 を返す | 403 | △(意図した仕様かを確認) |
同じ存在しないURLの応答は、「エラー応答のデバッグ情報」と「エラー応答のヘッダー整合性」の判定にも使います。
ソフト404にはどんなリスクがあるか
ソフト404そのものから直接情報が盗まれるわけではありませんが、次のような二次的なリスクにつながります。
- 誤公開の見逃し:存在しないものも 200 になる環境では、自動診断や外部の通報が本当に露出しているファイルを判別しにくく、
.envやバックアップファイルの誤公開の発見が遅れます。 - 偵察への効果がないまま、防御側だけが不利になる:攻撃者側は本文差分で実在を判定できるため、ソフト404は防御効果をほとんど持ちません。一方で防御側の監視だけが不利になります。
- Web Cache Deception:存在しないパスに動的ページ(ログイン後画面など)を 200 で返す構成では、CDN が拡張子だけを見てキャッシュした場合に、他人の画面が第三者へ配信されるおそれがあります。
- 任意パスの200応答による誤認:任意のパスが200を返す構成では、第三者が「自治体サイト上の存在しないURL」を作ってリンクを流布しても、受け手やクローラーが正規ページと区別しにくくなります。
- 障害の見逃し:本来の404がサーバーエラーで500になっていても、ステータスを監視していなければ気付けません。
存在しないURLに404を返す設定方法(Apache・nginx・IIS・Next.js)
Apache(.htaccess)
# 相対パス(ローカルURL)で指定すると、404 ステータスのまま本文を返す
ErrorDocument 404 /errors/404.html
ErrorDocument 410 /errors/410.html
# 削除済みで恒久的に無いことが明らかなページは 410
Redirect gone /old/kouhou2015.html
Apache の ErrorDocument に http:// から始まる完全URLを指定すると、クライアントへリダイレクトを送るため、元の 404 ステータスが失われます。必ず / から始まるローカルパスを指定してください。
nginx
error_page 404 /errors/404.html;
location = /errors/404.html {
internal;
}
# 誤り:error_page 404 =200 /index.html; (ステータスを 200 に書き換えてしまう)
SPA 用の try_files $uri /index.html; を全体に設定すると、存在しないURLがすべて 200 になります。SPA が必要なパスだけに限定してください。
IIS(web.config)
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" path="/errors/404.html" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
responseMode="Redirect" はクライアントへリダイレクトを返すため避けます。ExecuteURL で静的ページを返す場合、ステータスが404のままかを必ず確認します。
Next.js(Vercel)
// app/not-found.tsx — 一致しないURLで表示(非ストリーミング応答は 404)
import Link from "next/link";
export default function NotFound() {
return (<main><h1>ページが見つかりません</h1><Link href="/">トップへ</Link></main>);
}
Next.js のドキュメントでは、not-found はストリーミングされた応答では 200、非ストリーミング応答では 404 を返すと説明されています。動的ルートで notFound() を呼ぶ場合は、loading.js によるストリーミングの有無も含めて curl でステータスを確認してください。next.config の rewrites で全パスを / に書き換える設定は、ソフト404の原因になります。
CMS(WordPress 等)
- テーマの
404.phpが存在し、プラグイン(「404をトップへリダイレクト」系)が無効であることを確認します。 - 自治体向け CMS(静的書き出し型)では、書き出しサーバー側の
ErrorDocument設定が必要です。
404ページに載せる内容
- 「お探しのページは見つかりませんでした」の説明、サイト内検索、トップ・よくある質問へのリンクを置く。
- 要求されたURLをそのまま本文へ埋め込む場合は、エスケープしてXSSを防ぐ。
- スタックトレースやサーバー名・バージョンを出さない(「エラー応答のデバッグ情報」)。
- セキュリティヘッダーを正常応答と同様に付ける(「エラー応答のヘッダー整合性」)。
サイトを壊さないためのガードレール
- 旧URLを一律 404 にすると、外部からのリンクや印刷物のQRコードが切れます。移転したページは個別に 301 で新URLへ、廃止したページは 404/410 と、対応表を作ってから切り替えます。
ErrorDocumentで指定した404ページ自体が存在しないと、Apache は既定のエラーページに加えて追加のエラーを記録します。ページの配置を先に確認します。
設定後の確認方法
# ステータスだけを確認(リダイレクトも追従して最終結果を見る)
curl -s -o /dev/null -L -w "%{http_code} %{url_effective}\n" https://www.example.lg.jp/no-such-page-$(date +%s)
# リダイレクトの有無を確認
curl -sI https://www.example.lg.jp/no-such-page-test | head -n 5
404 または 410 が表示され、url_effective が要求したURLのままであれば適切です。
よくある質問(FAQ)
ソフト404とは何ですか?
存在しないURLに対して、404や410ではなく200(OK)を返したり、トップページへリダイレクトして最終的に200になったりする状態です。見た目は「ページが見つかりません」でも、ステータスコード上は「存在する」と扱われます。
存在しないURLはトップページへリダイレクトしたほうが親切ではありませんか?
利用者には何が起きたか分からず、検索エンジンにはソフト404として扱われます。Google Search Consoleのヘルプも、存在しないページをホームページへリダイレクトする方法を避けるよう求めています。404応答の本文に検索窓や主要リンクを置くのが適切です。
404と410はどう使い分けますか?
404は対象リソースが見つからない(または存在を開示したくない)ことを示し、410は対象リソースが恒久的に利用できなくなった可能性が高いことを示します。削除済みで今後も戻らないことが明らかなページには410を使えます。
存在しないURLに403を返すのは間違いですか?
RFC 9110上、存在を隠したいサーバーが禁止の代わりに404で応答してよいとされており、403自体は仕様違反ではありません。ただし「存在するが禁止」と区別できなくなるため、セキュリティAIチェッカーでは意図どおりかを確認してもらうため△としています。
カスタム404ページを作れば問題ありませんか?
見た目のページが正しくても、ErrorDocumentの指定方法やCMSの設定によってはステータスが200になっていることがあります。ブラウザの表示ではなく、curlなどでステータスコードを確認してください。
Next.jsのnot-foundページは404を返しますか?
Next.jsのドキュメントでは、not-foundは非ストリーミング応答では404、ストリーミングされた応答では200を返すと説明されています。loading.jsによるストリーミングの有無も含め、デプロイ後にcurlでステータスを確認してください。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- RFC 9110 HTTP Semantics 15.5.5 404 Not Found
- RFC 9110 HTTP Semantics 15.5.11 410 Gone
- Google Search Console ヘルプ「404 (Page Not Found) errors」
- Google Crawling Infrastructure:How HTTP Status Codes Affect Google's Crawlers
- OWASP ASVS 5.0.0 V14 Data Protection(V14.2.5)
- OWASP WSTG-ERRH-01 Testing for Improper Error Handling
- Next.js Docs「not-found.js」
- Apache HTTP Server ErrorDocument ディレクティブ
- nginx error_page ディレクティブ