結論(下層・エラー応答のバージョン/デバッグ情報)
下層・エラー応答のバージョン/デバッグ情報とは、トップページ以外の下層ページやエラー時の応答に含まれる、Webサーバー・実行環境・CMSのバージョン番号や、スタックトレース・SQLエラー・サーバー内部パスなどの情報です。版数は既知脆弱性の絞り込みに、デバッグ情報はSQLインジェクションなどの攻撃に直接使われるため、ServerTokens Prod、expose_php = Off、display_errors = Offなどで外部に出さないことが推奨されます。
この記事のポイント
- 露出箇所はServerヘッダー、X-Powered-Byヘッダー、meta generator、本文中のデバッグ出力の4種類です。
- バージョン非公開はASVS 5.0.0 V13.4.6(L3)、エラー時の汎用メッセージはV16.5.1(L2)の要件です。
- 自治体サイトでは下層に施設予約・電子申請など別システムが同居し、そこだけ情報が漏れていることがあります。
- セキュリティAIチェッカーは最大3ページを確認し、版数のみなら△、デバッグ情報があれば×と判定します。
- 版数を隠すことはパッチ適用の代わりにならないため、サポート期間と更新状況も必ず確認します。
| 診断項目名 | 下層・エラー応答のバージョン/デバッグ情報 |
|---|---|
| 項目ID | crawl.disclosure-coverage |
| 分類 | 公開ファイル・情報露出 |
| 重大度・配点の重み | 中(medium) 重み 2 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V13.4.6(L3:バックエンド構成要素の詳細なバージョン情報を公開しない)、V13.4.2(L2:本番環境でデバッグモードを無効化)、V16.5.1(L2:予期しないエラー時は汎用メッセージを返し、スタックトレース・クエリ等を露出しない)、OWASP WSTG-INFO-02(Fingerprint Web Server)、WSTG-ERRH-01(Testing for Improper Error Handling)、CWE-200、CWE-209 |
下層・エラー応答のバージョン/デバッグ情報とは
下層・エラー応答のバージョン/デバッグ情報とは、トップページ以外の下層ページやエラー時の応答に含まれる、Webサーバーや実行環境のバージョン番号、CMSのバージョン、例外のスタックトレースやサーバー内部のファイルパスといった情報のことです。セキュリティAIチェッカーのこの項目は、トップページと下層ページの応答にこれらの情報が含まれていないかを確認します。
トップページだけを見る「サーバーバージョンを露出していない」や、存在しないURLの404応答を見る「エラー応答のデバッグ情報」を補完し、「下層に進むと別のアプリ・別のサーバーが応答していて、そこだけ情報が漏れている」状況を拾うための網羅性項目です。バージョン情報だけなら△(warn)、例外詳細などのデバッグ情報が出ていれば×(fail)とします。
何が「情報露出」になるのか
| 露出箇所 | 例 | 意味 |
|---|---|---|
Server ヘッダー | Apache/2.4.41 (Ubuntu)、nginx/1.18.0、Microsoft-IIS/10.0 | Webサーバーの製品名と版数 |
X-Powered-By ヘッダー | PHP/7.4.3、ASP.NET、Next.js | 実行環境・フレームワーク |
<meta name="generator"> | WordPress 6.4.2、Joomla! - Open Source Content Management | CMSと版数 |
| 本文中のデバッグ出力 | Fatal error: Uncaught Exception、Stack trace:、SQLSTATE[42S02]、/var/www/html/... | 例外・SQLエラー・内部パス |
バージョン情報やデバッグ情報の露出はなぜ問題なのか
バージョン番号は「攻撃の下調べ」を楽にする
バージョン番号そのものは脆弱性ではありません。しかし攻撃者は版数から既知脆弱性(CVE)を絞り込めるため、情報を伏せることは「調査コストを上げる」多層防御の一部になります。OWASP ASVS 5.0.0でもバージョン非公開(V13.4.6)はLevel 3(高保証)の要件に位置付けられています。
デバッグ情報はより直接的に攻撃を助ける
一方、スタックトレースやSQLエラーの露出はより直接的です。ファイル配置、使用ライブラリ、データベースのテーブル名、SQL文の断片などが分かり、SQLインジェクション等の攻撃の成功確率を大きく上げます。
| 要件 | 内容 |
|---|---|
| ASVS 5.0.0 V16.5.1(L2) | 予期しないエラーでは汎用メッセージを返し、スタックトレースやクエリ、秘密鍵、トークンなどを露出しない |
| ASVS 5.0.0 V13.4.2(L2) | 本番環境のデバッグモードを無効化する |
| ASVS 5.0.0 V13.4.6(L3) | バックエンド構成要素の詳細なバージョン情報を公開しない |
| OWASP WSTG-INFO-02 / WSTG-ERRH-01 | Webサーバーのフィンガープリント調査/不適切なエラー処理の検査 |
| CWE-200 / CWE-209 | 権限のない者への機微情報の露出(Exposure of Sensitive Information to an Unauthorized Actor)/機微情報を含むエラーメッセージの生成(Generation of Error Message Containing Sensitive Information) |
なぜ「下層」と「エラー応答」を見る必要があるのか
自治体サイトでは、CMS本体と、施設予約・電子申請・検索・地図などの別システムが同一ドメインの下層に同居していることが多く、それぞれ別のサーバー設定を持っています。トップページがCDN経由で整っていても、下層の別システムでは古い設定のままということが珍しくありません。
情報露出についてよくある誤解
- 「バージョンを隠せば安全」:隠蔽はパッチ適用の代わりになりません。攻撃ツールは版数を確認せずに既知の攻撃を試すことも多く、最優先は更新です。
- 「トップページで確認したから大丈夫」:上記のとおり、下層には別システム・別サーバーが同居していることがあります。
- 「エラー画面は利用者が見ないから問題ない」:攻撃者は意図的に不正な値を送ってエラーを起こします。エラー時の応答こそ確認が必要です。
下層・エラー応答のバージョン/デバッグ情報の診断基準(セキュリティAIチェッカー)
取得方法
- トップページの応答(ヘッダー・本文)を使用します。
- V2診断で集めた同一オリジンの巡回ページ候補のうち、トップページ以外の先頭2件をGETで追加取得します(1件あたり5秒・180KB上限、リダイレクト最大2回、別オリジンへ移動した応答は除外)。
- 判定対象は最大3ページです。存在しないURLへの404応答は、本項目ではなく「エラー応答のデバッグ情報」で確認します。
露出兆候の判定ロジック
各ページについて、次のいずれかに該当すれば「露出兆候あり」と数えます。
| 種別 | 条件 |
|---|---|
| バージョン | Server ヘッダーに apache/数字、nginx/数字、iis/数字、php/数字 の形がある(Microsoft-IIS/10.0 も該当) |
| バージョン | X-Powered-By ヘッダーが存在する(値に版数がなくても該当) |
| バージョン | HTML内の <meta name="generator" content="...">(引用符付きで、name→content の順に書かれたもの)の値に数字が含まれる |
| デバッグ | 本文に stack trace:、uncaught 〜、sqlstate[、/var/www/、C:\inetpub\・C:\xampp\・C:\users\(ドライブ文字は C 以外も対象)のいずれかがある(大文字小文字を区別しない) |
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 判定対象の全ページ(最大3ページ)で上記の兆候がない | 重み2 × 1.00 |
| △ 要確認(warn) | バージョン系の兆候のみがある | 重み2 × 0.45 |
| × 要改善(fail) | 1ページでもデバッグ系の兆候がある | 重み2 × 0 |
| 対象外(na) | なし(トップページは常に判定可能) | — |
Server: ApacheやServer: nginxのように版数のない値はpassです。X-Powered-Byは値に関係なく存在だけでwarnになります。フレームワーク名だけでも攻撃対象の絞り込みに使えるためです。- 本文の文字列一致による判定のため、セキュリティ解説記事などで
/var/www/のような文字列を本文に掲載している場合は誤検知になり得ます。証拠欄の「該当ページ数/判定ページ数」を手がかりに、該当ページを目視で確認してください。 - CMSの生成ツール情報の単独確認は「生成ツール情報を露出していない」でも行います。
自治体サイトでの判定例
| 状況 | 判定 |
|---|---|
トップはCDN経由で Server ヘッダーに版数なし、下層の「施設予約」入口が別サーバーで Server: Apache/2.4.6 (CentOS) PHP/7.2.24、X-Powered-By: PHP/7.2.24 | △ |
下層のイベント検索ページが、パラメータ不備で Fatal error: Uncaught PDOException: SQLSTATE[...] in /var/www/html/search.php:52 を表示 | × |
WordPress製サイトで <meta name="generator" content="WordPress 6.5.2"> が全ページに出力 | △ |
バージョン/デバッグ情報が露出しているとどんなリスクがあるか
- 既知脆弱性の効率的な探索:版数が分かると、攻撃者は該当するCVEとエクスプロイトを即座に選べます。サポート終了版(例:PHP 7系、CentOS 7同梱のApache)が見えると、優先的な標的になり得ます。
- SQLインジェクション等の成功率向上:SQLエラー文はデータベース製品、テーブル名、クエリ構造を示し、ブラインドでの試行を不要にします。
- 内部構成の把握:
/var/www/html/やC:\inetpub\wwwroot\のようなパスは、OSやディレクトリ構成を示し、パストラバーサルやファイル読み出し攻撃の足がかりになります。 - 自治体特有の影響:委託先ごとに異なるシステムが同居するため、1つのシステムの露出から他システムの構成が推測されることもあります。
バージョン/デバッグ情報を隠す設定方法(Apache・nginx・IIS・PHP・Next.js・CMS)
Apache
# httpd.conf(ServerTokensは.htaccessでは設定不可)
# Server: Apache のみにする(既定はFull)
ServerTokens Prod
# エラーページ等のフッター署名を出さない(既定もOff)
ServerSignature Off
# X-Powered-By を除去(mod_headers)
<IfModule mod_headers.c>
Header always unset X-Powered-By
Header unset X-Powered-By
</IfModule>
Apacheの設定ファイルでは、ディレクティブと同じ行にコメントを書けません(構文エラーになります)。PHPの X-Powered-By は php.ini の expose_php = Off で根本的に止められます(expose_php は .user.ini では変更できません)。
共有ホスティングでhttpd.confを触れない場合は、.htaccess の Header unset X-Powered-By と、.user.ini での display_errors = Off が現実的な手段です(.htaccess の php_value はmod_php以外の環境で500エラーになるため使わないでください)。
nginx
http {
server_tokens off; # 既定は on(Serverヘッダーとエラーページに版数)
fastcgi_hide_header X-Powered-By;
proxy_hide_header X-Powered-By;
}
IIS(web.config)
<configuration>
<system.webServer>
<security>
<!-- IIS 10.0(Windows Server バージョン1709/2019以降)で有効。2016では効かない -->
<requestFiltering removeServerHeader="true" />
</security>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<httpErrors errorMode="DetailedLocalOnly" />
</system.webServer>
<system.web>
<customErrors mode="RemoteOnly" />
<httpRuntime enableVersionHeader="false" />
<compilation debug="false" />
</system.web>
</configuration>
enableVersionHeader="false" は X-AspNet-Version を消します。customErrors と httpErrors で、外部からのアクセスには詳細エラーを出さないようにします。
PHP(php.ini / .user.ini)
; expose_php は php.ini のみ有効
expose_php = Off
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log ; 公開ディレクトリ外
Next.js(Vercel)
// next.config.js
module.exports = {
poweredByHeader: false, // 既定では X-Powered-By: Next.js を付与
};
本番ビルド(next build)では、例外のスタックトレースはブラウザに表示されません。next dev をそのまま公開しないことが前提です。
CMS
- WordPress:テーマの
functions.phpにremove_action('wp_head', 'wp_generator');を追加するとgeneratorメタタグが出なくなります。WP_DEBUGは本番でfalseにします。 - その他の商用CMS:管理画面のメタ情報出力設定、またはテンプレートからgeneratorを削除します。
段階的な手順
| 手順 | 内容 |
|---|---|
| 1 | 本診断の証拠欄(該当ページ数)を手がかりに、下記の確認コマンド等でどのページに何が出ているかを特定します |
| 2 | デバッグ情報(fail要因)を最優先で止めます。アプリの設定をデバッグモードから本番モードに切り替え、エラーはログファイルへ記録します |
| 3 | 次にServer/X-Powered-By/generatorの版数を抑制します |
| 4 | 版数の非表示と同時に、該当ソフトウェアがサポート期間内か、最新の修正が適用されているかを必ず確認します |
設定後の確認方法
curl -sI https://www.example.lg.jp/ | grep -iE '^(server|x-powered-by|x-aspnet-version):'
curl -sI https://www.example.lg.jp/shisetsu/ | grep -iE '^(server|x-powered-by):'
curl -s https://www.example.lg.jp/ | grep -io '<meta[^>]*generator[^>]*>'
# 不正な値でのエラー応答を確認(自組織のサイトに限る)
curl -s 'https://www.example.lg.jp/search.php?id=%27' | grep -iE 'stack trace|sqlstate|uncaught|/var/www'
サイトを壊さないための注意点
display_errors = Offにすると画面にエラーが出なくなるため、障害調査用にlog_errors = Onとログ保存先を必ず設定してください。- Serverヘッダーを完全に消せない環境(一部のCDN・共有ホスティング)では、版数を出さない設定で十分です。
- 外部への不正値送信によるエラー確認は、自組織が管理するサイトに対してのみ実施してください。
よくある質問(FAQ)
Serverヘッダーにバージョンが出ているのは脆弱性ですか?
バージョン番号そのものは脆弱性ではありません。ただし攻撃者は版数から既知脆弱性(CVE)を絞り込めるため、伏せることは調査コストを上げる多層防御の一部になります。ASVS 5.0.0でもバージョン非公開はLevel 3の要件です。
X-Powered-Byに版数がなくても△になるのはなぜですか?
X-Powered-Byは値に関係なく存在だけで△になります。フレームワーク名だけでも攻撃対象の絞り込みに使えるためです。php.iniのexpose_php = Offや、nginxのfastcgi_hide_header、Next.jsのpoweredByHeader: falseで消せます。
スタックトレースやSQLエラーが表示されると、なぜ×なのですか?
ファイル配置、使用ライブラリ、データベースのテーブル名、SQL文の断片などが分かり、SQLインジェクション等の攻撃の成功確率を大きく上げるためです。ASVS V16.5.1は予期しないエラーでは汎用メッセージを返すことを、V13.4.2は本番環境のデバッグモード無効化を求めています。
共有ホスティングでhttpd.confを触れない場合はどうすればよいですか?
.htaccessのHeader unset X-Powered-Byと、.user.iniでのdisplay_errors = Offが現実的な手段です。expose_phpは.user.iniでは変更できません。.htaccessのphp_valueはmod_php以外の環境で500エラーになるため使わないでください。
セキュリティ解説の記事を載せているページが×になりました。誤検知ですか?
本文の文字列一致で判定しているため、/var/www/ のような文字列を本文に掲載していると誤検知になり得ます。証拠欄の「該当ページ数/判定ページ数」を手がかりに、該当ページを目視で確認してください。
存在しないURLの404ページは、下層・エラー応答のバージョン/デバッグ情報の項目で確認されますか?
確認されません。存在しないURLへの404応答は「エラー応答のデバッグ情報」(response.debug-details)で確認します。この項目はトップページと下層ページ最大2件の応答を対象にしています。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- OWASP ASVS 5.0.0 V13 Configuration
- OWASP ASVS 5.0.0 V16 Security Logging and Error Handling
- OWASP WSTG Fingerprint Web Server(WSTG-INFO-02)
- OWASP WSTG Improper Error Handling(WSTG-ERRH-01)
- Apache HTTP Server core(ServerTokens / ServerSignature)
- nginx ngx_http_core_module(server_tokens)
- Microsoft Learn Request Filtering(removeServerHeader)
- Next.js poweredByHeader