結論(ソースマップ参照を公開していない)
ソースマップ参照を公開していないとは、本番サイトのHTMLやスクリプトに、圧縮前の元ソースとの対応表(ソースマップ)を指す「//# sourceMappingURL=...」の注釈を残していない状態です。注釈とマップが公開されていると、第三者が元のソースコード、コメント、内部APIのパスを容易に読めます。セキュリティAIチェッカーは、トップページのHTMLにこの注釈が1件でもあれば △ 要確認と判定します。
この記事のポイント
- ソースマップはデバッグ用ファイルで、sourcesContent があればマップ1つで元のソースコードを完全に復元できます。
- 参照方法は末尾注釈(//# sourceMappingURL=)とHTTPヘッダー(SourceMap:)の2つで、ヘッダーが優先されます。
- 診断はトップページのHTML全文で sourceMappingURL= を数え、0件で ○、1件以上で △(重み2×0.45=0.9点)です。
- 注釈を消すだけでは不十分で、サーバー上の .map ファイル自体も本番から除くか配信拒否にします。
- 障害解析が必要なら hidden source map を生成してSentry等へアップロードし、公開サーバーには置きません。
| 診断項目名 | ソースマップ参照を公開していない |
|---|---|
| 項目ID | html.sourcemap |
| 分類 | 公開ファイル・情報露出 |
| 重大度・配点の重み | 中(medium) 重み 2 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V13.4.2(本番環境でデバッグ機能を無効化)・V13.4.7(Web層は特定の拡張子のみ配信し、ソースコード漏えいを防ぐ)、OWASP WSTG-INFO-05、ECMA-426(Source map format specification)、CWE-540、CWE-200 |
ソースマップ参照を公開していないとは(sourceMappingURLの確認)
ソースマップ参照を公開していないとは、本番サイトのHTMLに、ソースマップ(Source Map)を指す sourceMappingURL の注釈が含まれていない状態のことです。セキュリティAIチェッカーはこの項目(html.sourcemap)で、トップページのHTMLにソースマップへの参照注釈が残っていないかを確認します。
ソースマップは、圧縮・変換された本番用JavaScriptやCSSと、開発者が書いた元のソースコードとを対応付けるデバッグ用ファイルです。ブラウザの開発者ツールは、スクリプト末尾の //# sourceMappingURL=... という注釈を見つけるとマップを取得し、元のファイル名・行番号・場合によってはソース全文を表示します。
開発中は便利な仕組みですが、本番サイトで公開したままにすると、第三者が元のソースコード、コメント、内部APIのパス、ディレクトリ構成を容易に読めるようになります。
| 項目 | 内容 |
|---|---|
| 項目ID | html.sourcemap |
| 診断カテゴリ | 情報露出 |
| 重大度 | medium |
| 重み | 2 |
| 関連標準 | OWASP ASVS 5.0.0 V13.4.2・V13.4.7、OWASP WSTG-INFO-05、ECMA-426、CWE-540、CWE-200 |
| 関連項目 | 「ソースマップの原文公開」:同一オリジンJSの .map を実際に取得し、原文 sourcesContent の有無を判定 |
ソースマップの仕組み(ECMA-426の要点)
ソースマップは、Ecma InternationalのTC39がECMA-426(Source map format specification)として標準化している形式です。仕様の要点は次のとおりです。
- リンク方法1:ソース注釈。生成コードの末尾に
//# sourceMappingURL=<url>を書きます。生成側は//#のみを出力すべきですが、読み取り側は旧形式//@も受け付けます。CSSでは/*# sourceMappingURL=... */を使います。 - リンク方法2:HTTPヘッダー。
SourceMap: <url>ヘッダー(旧X-SourceMapは非推奨)。ヘッダーがあれば注釈より優先されます。 sourcesとsourcesContent。sourcesは元ファイルのパス一覧、sourcesContentは任意項目で、元ソースの全文を文字列として埋め込めます。sourcesContentがあると、マップ1つで元のソースコードが完全に復元できます。- データURI。
sourceMappingURL=data:application/json;base64,...のように、マップ自体をスクリプトに直接埋め込むこともできます(インラインソースマップ)。
ブラウザ側の動作
一般の閲覧者のブラウザは、開発者ツールを開かない限りソースマップを取得しません。そのため、ソースマップを公開していても表示速度や通常の利用には影響せず、アクセスログにも .map へのリクエストはほとんど現れません。
逆に言えば、.map へのアクセスがログに記録されている場合は、開発者ツールを使った閲覧や自動収集ツールによる取得である可能性が高く、公開に気付く手掛かりになります。
インラインソースマップ(data: URI)の場合は、マップがスクリプト本体と一緒に必ず配信されるため、ファイルサイズが大きく増えるうえ、ソース全文が常に全閲覧者へ送られます。本番では最も避けるべき形態です。
ソースマップを公開すると何が漏れるのか
| 漏れる情報 | 具体例 |
|---|---|
| 元のソースコード | minify前の変数名、関数名、ロジック全体 |
| 開発者コメント | // TODO: 認証チェックを後で追加、テスト用URL、担当者名 |
| 内部構成 | webpack:///src/admin/...、/home/developer/project/... 等のローカルパス |
| 隠しAPI | 画面に出ていない管理用エンドポイントや機能フラグ |
主なビルドツールの既定動作
本番のソースマップは、多くの場合ビルドツールの設定で出力されます。主なツールの本番ビルドの既定は次のとおりです。
| ツール | 本番ビルドの既定 | 注意点 |
|---|---|---|
| Vite | build.sourcemap: false | true / 'inline' に変更していないか確認 |
| webpack | mode: 'production' では devtool 未指定時に出力しない | 設定ファイルで source-map を指定していると注釈付きで出力 |
| Next.js | productionBrowserSourceMaps: false | true にするとクライアント用マップが公開される |
| Sass(dart-sass CLI) | 既定でCSS用マップを生成 | --no-source-map で抑止 |
既定値はバージョンにより変わり得るため、実際のビルド成果物に .map と注釈が含まれていないかを最終確認してください。
ソースマップについてよくある誤解
- 「ソースマップがなければコードは読めない」:minify済みのコードも整形すれば読めます。ソースマップ非公開は「解析コストを上げる」対策であり、クライアント側に秘密を置いてよい理由にはなりません(秘密情報の直書きは「秘密情報らしき文字列がない」で確認します)。
- 「参照注釈を消せば安全」:
.mapファイル自体がサーバーに残っていれば、ファイル名を推測して取得できます(main.abc123.js→main.abc123.js.map)。注釈とファイルの両方を本番から除くのが確実です。 - 「ソースマップはバグ調査に必要」:エラー監視サービス(Sentry等)へマップをアップロードし、公開サーバーには置かない「hidden source map」運用が可能です。
ソースマップ参照を公開していないの診断基準(セキュリティAIチェッカー)
取得対象
- 入力URLのGET(リダイレクト最大4回追跡)で得た最終ページのHTML本文(最大2,000,000バイト、テキスト系Content-Typeのみ)。
- HTML内のインライン
script・style要素を含む全文が対象です。外部.jsファイルの中身はこの項目では読みません。
判定条件
本文中の sourceMappingURL= という文字列(大文字小文字を区別しない)の出現回数を数えます。
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 出現0件 | 重み2を満点で加算 |
| △ 要確認(warn) | 1件以上 | 重み2×0.45=0.9点 |
| (判定なし) | HTML本文を取得できない(非テキスト応答など) | 本項目は結果に出力されず、得点の分母にも入らない |
- 根拠欄には件数(「◯件のsourceMappingURL参照があります。」)を表示します。
- △ に留めているのは、参照があっても
.mapが実際には配信されていない(404)場合や、インラインスクリプト自体に秘密がない場合があり、HTMLだけでは影響度を確定できないためです。
関連項目「ソースマップの原文公開」との住み分け
実際に .map が取得できるか、原文 sourcesContent を含むかは、関連項目「ソースマップの原文公開」で評価します。この関連項目は、巡回で見つけた同一オリジンのスクリプト最大2件を取得し、SourceMap ヘッダーまたは注釈が指す同一オリジンの .map が200かつ sources または mappings を含むJSONであれば △、原文入りの sourcesContent を含めば × と判定します。data: URIの埋め込みマップは対象外です。
このページの項目は「HTMLに参照が残っているか」、関連項目は「マップの中身が実際に取れるか」を確認する、という役割分担です。
自治体サイトでの判定例
| 状況 | 判定 |
|---|---|
| 一般的なCMS(静的HTML出力)のトップページ | ○(多数) |
| Next.js・Nuxt・Vite等で構築した特設サイトで、ビルド時にインラインスクリプトへソースマップを付けたまま公開 | △ |
外部 .js の末尾にのみ注釈がある | 本項目は ○、「ソースマップの原文公開」側で検出 |
ソースマップを公開したままにするとどんなリスクがあるか
- 攻撃の下調べを容易にする:入力チェックがクライアント側だけで行われている箇所、管理画面のAPI、権限判定のロジックが読み取られ、攻撃対象の選定が短時間で済みます。
- 秘密情報の二次漏えい:開発時に一時的に書いたAPIキーやテスト用アカウントがコメントや未使用コードとして残り、ソースマップ経由で露出することがあります。
- 委託先の内部情報露出:ビルド環境のユーザー名やディレクトリ構成から、開発事業者や利用ツールが推測されます。
単独で直ちに侵害につながる脆弱性ではないため重大度は medium ですが、他の弱点を見つけやすくする「増幅要因」として扱うべき項目です。
ソースマップを本番で無効化する方法(Vite・webpack・Next.js・Apache・nginx・IIS)
1. ビルド設定で本番のソースマップ出力を止める
Vite
// vite.config.js
export default {
build: {
sourcemap: false, // 監視サービスへ送る場合は 'hidden'(注釈を付けずに.mapだけ生成)
},
};
webpack
// webpack.config.js(本番)
module.exports = {
mode: 'production',
devtool: false, // または 'hidden-source-map'
};
Next.js
// next.config.js
module.exports = {
productionBrowserSourceMaps: false, // 既定値はfalse。trueにしていないか確認
};
Sass(dart-sass CLI):既定でCSS用マップを生成するため、本番ビルドでは --no-source-map を付けます。
hidden 系の設定では .map ファイルは生成されるため、デプロイ対象から除外する手順(次項)とセットで運用してください。
2. サーバー側で .map を配信しない
Apache(.htaccess)
<FilesMatch "\.map$">
Require all denied
</FilesMatch>
nginx
location ~* \.map$ {
return 404;
}
IIS(web.config)
<configuration>
<system.webServer>
<security>
<requestFiltering>
<fileExtensions>
<add fileExtension=".map" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>
3. デバッグ用途はエラー監視サービスへ
Sentry等にはCI上でソースマップをアップロードし、アップロード後にビルド成果物から .map を削除します。これにより、本番の利用者には公開せず、障害解析では元の行番号を参照できます。
4. 確認方法(curl)
# HTML内の参照注釈
curl -s https://www.city.example.lg.jp/ | grep -c 'sourceMappingURL='
# 主要JSの末尾注釈と、SourceMapヘッダー
curl -s https://www.city.example.lg.jp/assets/main.js | tail -c 300
curl -sI https://www.city.example.lg.jp/assets/main.js | grep -i 'sourcemap'
# .mapが取得できないこと(403/404が望ましい)
curl -s -o /dev/null -w '%{http_code}\n' https://www.city.example.lg.jp/assets/main.js.map
修正後はセキュリティAIチェッカーで再診断し、本項目が ○ になったこと、「ソースマップの原文公開」でも指摘がないことを確認します。
サイトを壊さないための注意点(ガードレール)
.mapの配信拒否は、ブラウザの開発者ツールでの調査が不便になるだけで、サイトの表示や動作には影響しません。- CMSのテーマや外部ライブラリ(jQuery、Bootstrap等の配布物)にも注釈が含まれることがあります。外部CDNのライブラリの注釈は自組織のコード漏えいではないため、自組織が開発・委託したコードを優先して対処してください。
FilesMatch "\.map$"の設定は、拡張子.mapを持つ地図データ等(例えばイメージマップ定義を.mapで配布している場合)も遮断します。該当ファイルがないか事前に確認してください。
よくある質問(FAQ)
ソースマップを本番で公開すると何が漏れますか?
minify前の変数名・関数名・ロジック全体、開発者コメント(TODOやテスト用URL、担当者名)、webpack:///src/... やローカルパスなどの内部構成、画面に出ていない管理用エンドポイントや機能フラグです。sourcesContent が含まれていれば元ソースの全文が復元できます。
sourceMappingURL の注釈を消せば安全ですか?
注釈を消すだけでは不十分です。.map ファイルがサーバーに残っていれば、main.abc123.js から main.abc123.js.map のようにファイル名を推測して取得できます。注釈とファイルの両方を本番から除いてください。
ソースマップを置くとサイトの表示が遅くなりますか?
一般の閲覧者のブラウザは開発者ツールを開かない限りソースマップを取得しないため、外部 .map ファイルなら表示速度に影響しません。ただしdata: URIのインラインソースマップは本体と一緒に必ず配信されるため、ファイルサイズが大きく増え、ソース全文が全閲覧者に送られます。
本番でもバグ調査のためにソースマップを使いたい場合は?
hidden source map(注釈を付けずに .map だけ生成する設定)でビルドし、CI上でSentry等のエラー監視サービスへアップロードしてから、ビルド成果物から .map を削除します。公開せずに元の行番号で障害解析ができます。
外部JSファイルの末尾にだけ sourceMappingURL がある場合、この項目で検出されますか?
検出されません。この項目が読むのはトップページのHTML本文(インラインのscript・styleを含む)だけです。外部JSの .map が実際に取得できるか、原文を含むかは「ソースマップの原文公開」(public.source-map-content)の項目で評価します。
HTMLにsourceMappingURLの参照が残っていると、なぜ × ではなく △ 判定なのですか?
参照注釈があっても .map が実際には配信されていない(404)場合や、インラインスクリプト自体に秘密がない場合があり、HTMLだけでは影響度を確定できないためです。単独で直ちに侵害につながるものではないため、重大度も medium としています。
この項目を含む127項目を、URLを入れるだけで無料診断します。