本番環境の詳細なエラーページとスタックトレース
未処理の例外や存在しないルートへのプローブによって、本番環境でフレームワークのデバッグ用エラー画面が表示されると、ファイルパス、行番号、ライブラリのバージョン、場合によっては環境変数といった、サーバーの地図を攻撃者に渡すことになります。対策は、ユーザーには汎用的なエラーレスポンスを返し、詳細はチームが管理するサーバー側のサービスにだけ記録することです。
これは何か
どのWebフレームワークにも、組み込みのデバッグ用エラー画面があります。Djangoの黄色い例外ページ、LaravelのIgnition画面、Next.jsの開発用オーバーレイ、Expressのデフォルトの例外ダンプなどです。開発中は非常に役立ちますが、本番ビルドでは意図的に無効化されています。リスクとなるのは、デバッグモードがオフにされず有効なままのフレームワークのエラーページや、生の例外オブジェクトをそのままレスポンス本文に返すカスタムエラーハンドラーです。
AppSafeは、サイトに存在しないはずのパスをリクエストすることで詳細なエラーを検出します。レスポンス本文がフレームワークのエラーページによくあるパターン(Pythonのトレースバック、Node.jsの例外ダンプ、.NETの例外詳細、Rails.rootのパスなど)に一致した場合、「エラー処理と耐障害性」カテゴリで深刻度「中」として報告します。
なぜ重要か
スタックトレースからは、言語とフレームワークのバージョン、アプリ内部のディレクトリ構造、失敗した正確なファイルと行、そこに至った呼び出しの連鎖がわかります。CVEデータベースと組み合わせれば、発見から標的型エクスプロイトまでの時間が短縮されます。特定のフレームワークやライブラリのバージョンにある既知の脆弱性では顕著です。
デバッグページには、リクエストデータ、環境変数の一部、SQLの断片が表示されることもあり、ブラウザに届くべきではないユーザー入力やサーバー内部の値が意図せず漏れることがあります。
直し方
Next.jsのAPIルートやRoute Handlerでは、例外を明示的にキャッチし、完全なエラーはサーバー側に記録して、呼び出し元には汎用的なステータスを返します。
// app/api/example/route.ts
export async function GET() {
try {
// ... handler logic ...
} catch (err) {
console.error(err); // logs stack trace to your server/monitoring only
return new Response("Internal Server Error", { status: 500 });
}
}Next.jsは本番環境の未処理エラーに対してpages/500.tsx(App Routerではapp/error.tsx)をレンダリングします。技術的な詳細を含まないわかりやすいメッセージを入れ、Sentryのようなエラー監視サービスを接続して実際の例外を記録してください。
アプリ層をすり抜けたエラーについては、nginxがすべての5xxレスポンスをブラウザに届く前に静的ページに差し替えられます。
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
internal;
}FAQ
Next.jsは本番ビルドでスタックトレースを表示しますか?
開発用オーバーレイは本番環境ではすでに表示されません。本当のリスクは、例外をキャッチしてそのままレスポンスにシリアライズするカスタムのRoute HandlerやAPIルートです。これはフレームワーク自身では防げません。
AppSafeはどのように詳細なエラーをプローブしますか?
サイトに存在しないURLをリクエストし、レスポンス本文から「Traceback (most recent call last)」「Stack trace:」「Unhandled Runtime Error」「Exception Details:」など、Python、Node.js、PHP、Java、Ruby、.NETのフレームワークに特有の目印となるフレーズを探します。
404ページにスタックトレースは表示されていないのに、AppSafeに報告されました。なぜですか?
スキャナーは幅広いパターンに一致させており、その一部は部分的または伏せ字にされたエラーレスポンスにも現れます。404や500のレスポンス本文のどこかに、例外クラス名、内部のファイルパス、フレームワークの識別子が含まれていないか確認してください。コメントや非表示の要素の中も含みます。