本番のエラー画面に内部コードが丸見えだった——スタックトレース漏洩と当日対応の記録
2026-05-12
🎯 結論
今週、本番環境で 5xx エラーが発生した際に、フレームワークのデバッグ用スタックトレースがそのままブラウザに表示されていた。内部のファイルパス・クラス名・処理経路の断片が外部から見える状態だった。発見した時点で即日修正し、エラーハンドリングをカスタム画面に差し替えた。「本番に切り替えた」という意識が、フレームワーク内部の下位コンポーネントまで設定が連動して切り替わるという誤った前提につながっていた。
◾️ 発見:エラー画面がデバッグ情報を返していた
きっかけは、特定のページアクセスで 500 エラーが返るという報告だった。調査のためにブラウザで確認したところ、デバッグ用のスタックトレース——エラーが発生したファイルパス・関連するクラス名・処理の呼び出し履歴の一覧——がそのまま画面に表示されていた。
この画面は開発環境では有用だ。エラーがどの行で発生したか、どのコンポーネントが関与しているか、を即座に確認できる。しかし本番環境でこれが表示されると、システム内部の構造情報が外部に漏れる。悪意ある第三者にとって、スタックトレースはシステムの設計を読み解く手がかりになる。
最初に確認したのは「本番設定でデバッグモードが有効になっているか」だった。アプリケーション本体の設定は本番用になっていた。問題は別の場所にあった。
◾️ 原因:フレームワーク内の二層構造
今回使用しているアプリケーションフレームワークは、内部に複数のサブコンポーネントを組み合わせて動いている。その中に例外処理を担うコンポーネントがある。
通常はアプリケーション層のエラーハンドラーがすべての例外を先に捕捉し、適切なレスポンスに変換する。しかし今回は、特定の経路でサブコンポーネント側の例外処理がアプリケーション層より先に動いていた。サブコンポーネントは独自のデバッグ設定を持ち、その設定が本番用に切り替えられていなかった。
アプリケーション本体の設定を本番用に切り替えた際、そのアプリケーションが使用しているサブコンポーネントの設定は見落とされていた。「フレームワークの設定を切り替えた」という意識が、「そのフレームワーク全体が本番設定で動いている」という誤った確信につながった。
サブコンポーネントが独立した設定ファイルを持つことは珍しくない。上位の設定を切り替えても、下位が自動で追従するとは限らない。今回の問題は設定の見落としではなく、「どこが設定を持っているか」の把握が不完全だったことだ。
◾️ 対応:カスタムエラー画面への差し替え
修正は二段階で行った。
第一段階として、即日対応でサブコンポーネント側のデバッグ出力を無効にした。「漏洩の遮断」を先行させた。この変更で 5xx エラー時のスタックトレース表示は止まった。
第二段階として、5xx エラー全体に対してカスタムのエラー画面を返すよう設定した。どのコンポーネントが例外を捕捉しても、最終的に外部に返る出力は一か所で制御される構成にした。これによって「どの処理経路でエラーが起きても内部情報は外に出ない」状態を確保した。
修正にかかった時間は数時間だった。発見から修正完了まで当日中に終えられた。
◾️ 教訓と SOP 化
今回の件から引き出した原則を記録する。
原則 1: 本番環境のエラー画面を意図的に確認する
デプロイ後に「エラーが起きたときに何が返るか」を確認しているチームは多くない。本番で意図的にエラーを発生させ、返ってくる画面の内容を確認するステップをデプロイ検証に組み込む。正常系の動作確認だけでは異常系の出力は見えない。検証項目一覧に「404 と 500 の表示内容確認」を追加する。
原則 2: フレームワーク内部のサブコンポーネント設定も確認する
「アプリケーションの設定を切り替えた」はそのアプリケーション全体の設定が切り替わったを意味しない。複数のコンポーネントを組み合わせて動くシステムでは、各コンポーネントが独立した設定を持つ可能性がある。本番移行チェックリストに「主要サブコンポーネントの設定確認」を追加し、上位設定の変更で自動追従しない項目を洗い出しておく。
原則 3: エラーハンドリングは単一の出口に集約する
どの層でエラーが起きても、外部に返る出力は一か所で制御される設計にする。複数の処理層がそれぞれ独自のエラー出力を持つ構成は、見落としが生まれやすい。カスタムエラー画面を「最後の砦」として必ず通過させることで、予期しない情報漏洩を防ぐ。
今回の事象は、発見できたのは「調査中に偶然確認した」からだ。定期的なエラー画面の確認手順が存在していれば、発見はもっと早かった可能性がある。また、本番稼働中の期間に同じ画面が返り続けていた可能性も排除できない。修正は完了したが、「いつから漏れていたか」は特定できていない。この不確実性を記録に残す。発見を偶然に頼らない仕組みをどこに組み込むか——次の課題として引き継ぐ。