結論(ソースマップの原文公開)
ソースマップの原文公開とは、圧縮・難読化したJavaScriptと元のソースコードを対応付けるソースマップ(.mapファイル)が本番サーバーで誰でも取得でき、特にsourcesContentに元のコード全文が入っている状態です。ファイル構成・関数名・コメントまで読めるため、内部構造の把握や脆弱性探索に悪用されます。本番の配備物から.mapを除き、サーバーでも.mapへのアクセスを拒否するのが対策です。
この記事のポイント
- ソースマップのsourcesに内部のファイル構成が、sourcesContentに元のコード全文がコメント付きで入ります。
- ブラウザは開発者ツールを開いたときだけ.mapを読むため、削除しても表示・動作は変わりません。
- hidden設定(hidden-source-map、Viteのsourcemap: 'hidden')は参照コメントを付けないだけで、.mapファイル自体は出力されます。
- セキュリティAIチェッカーはsourcesContentに原文があれば×、ソースマップだけ公開されていれば△と判定します。
- 対策はビルド設定で本番の.mapを出さないことと、Webサーバーで\.map$へのアクセスを拒否することの二重化です。
| 診断項目名 | ソースマップの原文公開 |
|---|---|
| 項目ID | public.source-map-content |
| 分類 | 公開ファイル・情報露出 |
| 重大度・配点の重み | 中(medium) 重み 3 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V13.4.2(本番環境でデバッグ機能を無効化し情報漏えいを防ぐ)、V15.2.3(本番環境に不要な開発用機能を含めない)、OWASP WSTG-INFO-05(Review Web Page Content for Information Leakage「Identifying Source Map Files」)、ECMA-426 Source Map Format Specification(ソースマップの形式とsourcemap HTTPヘッダー)、CWE-540(Inclusion of Sensitive Information in Source Code)、CWE-200(Exposure of Sensitive Information to an Unauthorized Actor) |
ソースマップの原文公開とは
ソースマップの原文公開とは、本番サーバーに置かれたソースマップ(.map ファイル)を誰でも取得でき、その中に開発者が書いた元のソースコードが含まれている状態です。
ソースマップは、圧縮・難読化・トランスパイルされたJavaScriptやCSSと、開発者が書いた元のソースコードとを対応付けるJSONファイルです。本来は開発時にブラウザの開発者ツールで元のコードを表示してデバッグするための仕組みですが、本番サーバーにそのまま配置すると、誰でも元のソースコードのファイル構成・関数名・コメント、場合によってはソースコードの全文を取得できます。
セキュリティAIチェッカーのこの項目は、診断対象サイトが読み込んでいる同一オリジンのJavaScriptからソースマップへの参照をたどり、ソースマップが公開されているか、さらにその中に元のソースコード全文(sourcesContent)が含まれているかを確認します。
ソースマップの構造(ECMA-426)
ECMA-426(Source Map Format Specification)によると、ソースマップは次のフィールドを持つJSONです。
| フィールド | 意味 |
|---|---|
version | 常に整数 3 |
file | 生成後ファイル名(任意) |
sourceRoot | sources の各要素に前置するパス(任意) |
sources | 元ソースファイルのパス一覧 |
sourcesContent | 元ソースの本文そのもの(任意) |
names | 元の識別子名(任意) |
mappings | 位置対応をエンコードした文字列 |
sources だけでも src/admin/userApi.ts のような内部のディレクトリ構成・ファイル名・利用ライブラリが分かります。sourcesContent があると、元のコードがコメント付きでそのまま読めます。webpack・Vite・Next.js などの既定のビルドでは、ソースマップを生成する設定にすると sourcesContent が含まれることが多い点に注意が必要です。
ソースマップはどのように読み込まれるのか(仕組み)
生成コードとソースマップの結び付け方
ECMA-426 では2つの方法が定義されています。
- 生成コード末尾のコメント
//# sourceMappingURL=main.js.map(利用側は旧形式//@も受け付ける) - HTTPレスポンスヘッダー
SourceMap: /static/main.js.map(旧名X-SourceMapは非推奨)
両方ある場合はHTTPヘッダーが優先されます。
削除してもサイトの表示・動作は変わらない
ブラウザは開発者ツールを開いたときにだけソースマップを取得するため、通常の閲覧には影響しません。そのため、ソースマップを削除してもサイトの表示・動作は変わりません。本番で .map を残しておく利点は、一般の利用者にとってはありません。
ソースマップについてよくある誤解
- 「難読化しているから安全」:ソースマップを公開すると難読化は事実上無意味になります。
- 「
.mapを消せば元コードは完全に見えない」:圧縮コード自体はブラウザに配信されるため読めます。ソースマップ非公開は解析コストを上げる対策であり、秘密情報をクライアントコードに置かないことが前提です。 - 「
hidden設定なら公開されない」:Vite のbuild.sourcemap: 'hidden'や webpack のhidden-source-mapは参照コメントを付けないだけで、.mapファイルは出力されます。配備対象から除外しないと、main.js.mapを推測すれば取得できます。
なお、ソースコードの中身ではなく、ファイルの存在そのものを確認する項目として、管理画面の入口を扱う「CMSセットアップ/管理入口の露出」や、API資料を扱う「API仕様・GraphQL開発画面の公開」があります。このページはソースマップによる原文の露出に絞って解説します。
ソースマップの原文公開の診断基準(セキュリティAIチェッカー)
取得対象と方法
- トップページと、巡回で取得した同一オリジンの追加ページ(最大2ページ)のHTMLから
<script src="...">を抽出します。 - 同一オリジンのスクリプトURLを重複除去し、先頭2件だけを対象にします。
- 各スクリプトをGETで取得し(500KBを超える場合は先頭500KBだけを取得、リダイレクトは最大2回追跡)、レスポンスヘッダー
SourceMap(なければ旧X-SourceMap)、どちらもなければ本文の//# sourceMappingURL=または//@ sourceMappingURL=(CSS形式の/*# ... */も可)から参照先を得ます。本文に複数ある場合は最後に現れたものを使います。 - 参照先が
data:URI(インラインソースマップ)の場合や外部オリジンの場合は取得しません。 - 同一オリジンの参照先をGETで取得します(500KBを超える場合は先頭500KBだけを取得)。追加診断のリクエストは診断全体で40件以内に制限されます。
判定条件
| 判定 | 条件 | 得点係数 |
|---|---|---|
| × 要改善(fail) | 有効なソースマップ(HTTP 200で、本文が { で始まり、"sources": または "mappings": のキーを含む)を取得し、かつ "sourcesContent": [ の配列内に文字列要素がある | 0 |
| △ 要確認(warn) | 有効なソースマップを取得したが、取得した範囲に sourcesContent がない、または全要素が null | 0.45 |
| ○ 問題なし(pass) | 対象スクリプトにソースマップ参照がない、参照先が200でない、またはソースマップ形式でない | 1 |
| 対象外(na) | 同一オリジンのJavaScriptを1件も発見できない | 計算から除外 |
重み3のため、× のときは満点から重み3分がまるごと失われ、△ のときは3×0.55=1.65分が失われます。診断結果の根拠欄には、sourcesContent を含むソースマップの件数、公開されているソースマップの件数、または確認したJavaScriptの件数が表示されます。
判定の限界
- 確認するのは先頭2本のスクリプトだけです。他のバンドルにだけソースマップがある場合は検出できません。
- スクリプト・ソースマップとも、500KBを超える部分は読みません。500KBを超えるスクリプトでは末尾の参照コメントに届かず、ヘッダーでの指定がなければ未検出(○ 側)になります。大きなソースマップで
sourcesContentが500KBより後ろにある場合は × ではなく △ にとどまります。大きなバンドルを使うサイトでは、後述の「確認方法」の手順で手動確認してください。 - 参照コメントを付けずに
.mapだけを配置した構成(hidden 設定)は、本項目では推測URLへのアクセスを行わないため検出しません。 data:URIで埋め込まれたインラインソースマップは追加取得しないため本項目の対象外です。インラインでも原文が含まれる点は同じリスクなので、手動確認が必要です。
自治体サイトでの判定例
| サイトの構成 | 判定 |
|---|---|
CMSが配信する jquery.min.js と自前の common.js だけを読み込む典型的な自治体サイトで、参照コメントがない | ○ |
防災マップや施設予約など、React/Vue で構築したページを同一ドメインで配信し、main.abc123.js.map に sourcesContent が含まれる | × |
jquery.min.js の末尾に //# sourceMappingURL=jquery.min.map が残り、その .map も配置されている | 該当内容により △ または × |
最後の例はオープンソースの原文であり秘密情報はありませんが、判定上は該当内容により △ または × になります。不要なファイルとして削除するのが簡単です。
ソースマップが公開されているとどんなリスクがあるか
- 内部構造の把握:ソースマップに含まれるファイル名やディレクトリ構成から、管理画面用のルート、未公開APIのエンドポイント、機能フラグ、内部ホスト名が判明します。OWASP WSTG-INFO-05 も、ソースマップがフロントエンドの脆弱性発見や機密情報収集を容易にすると指摘しています。
- 秘密情報の露出:開発者がコメントに残した検証用アカウント、APIキー、内部URL、TODOコメントがそのまま読めることがあります。ビルド時の環境変数がクライアントコードに埋め込まれていると、ソースマップの原文で変数名とともに判明します。
- 脆弱性探索の効率化:入力検証ロジックや認可判定をクライアント側で行っている箇所、
innerHTMLへの代入箇所などを、元のコードで容易に探せるため、DOM-based XSS などの攻撃準備が短時間で済みます。 - 委託先コードの流出:自治体が委託開発したシステムでは、著作物である委託先のソースコードが第三者に公開されることになり、契約上の問題にもなり得ます。
ソースマップを本番で公開しない設定方法(Next.js・Vite・webpack・Apache・nginx・IIS・Vercel)
1. ビルド設定で本番ソースマップを出さない
Next.js では、ブラウザ向けソースマップは本番で既定無効です。有効化している場合のみ戻します。
// next.config.js
module.exports = {
productionBrowserSourceMaps: false,
};
Vite(既定は false):
// vite.config.js
export default {
build: { sourcemap: false },
};
webpack:
// webpack.config.js(本番)
module.exports = {
mode: "production",
devtool: false, // エラー監視用に必要なら "hidden-source-map" または "nosources-source-map"
};
エラー監視サービスにソースマップが必要な場合は、hidden-source-map で生成し、監視サービスへアップロードした後に配備物から .map を削除します。原文を含めたくない場合は nosources-source-map(sourcesContent を出さない)を使います。
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>
Vercel の場合
Vercel では配備物に .map を含めないことが基本です。エラー調査のために残す場合は、プロジェクト設定(Settings → Deployment Protection)の Protected Source Maps を有効にすると、ブラウザ向け .map が Vercel Authentication の背後に置かれ、認証のない第三者には404が返ります(2026年5月提供開始。新規プロジェクトは既定で有効、既存プロジェクトは手動で有効化)。
3. 配布ライブラリの参照コメントを整理する
CMSのテーマなどに含まれる jquery.min.js の末尾の sourceMappingURL コメントは、.map を配置しない場合は不要です。削除しても動作には影響しません。開発者ツールで「ソースマップを読み込めない」という警告が出るだけです。
4. ソースマップ公開の確認方法
# スクリプト末尾の参照コメントとヘッダーを確認
curl -s https://www.example.lg.jp/js/main.js | tail -c 300
curl -sI https://www.example.lg.jp/js/main.js | grep -i sourcemap
# .map の公開と sourcesContent の有無を確認
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.lg.jp/js/main.js.map
curl -s https://www.example.lg.jp/js/main.js.map | grep -o '"sourcesContent"' | head -1
.map が403または404になり、スクリプト末尾に参照コメントがなければ対応完了です。対応後はセキュリティAIチェッカーで再診断し、判定が ○ になったことを確かめます。
サイトを壊さないための注意点(ガードレール)
- ソースマップの削除・拒否はサイトの表示や動作に影響しません。ただし、
.map以外の拡張子(例:.json)まで拒否しないよう、正規表現は\.map$に限定します。 - ソースマップを消しても、クライアントに配信したコードの中の秘密情報は残ります。APIキーなどはクライアントコードに置かず、サーバー側の環境変数とプロキシで扱ってください。
- 委託先にビルド成果物の納品条件として「本番配備物に
.mapを含めない」ことを明記すると再発を防げます。
よくある質問(FAQ)
ソースマップ(.map)を本番から削除するとサイトが動かなくなりますか?
動かなくなりません。ブラウザは開発者ツールを開いたときにだけソースマップを取得するため、通常の閲覧には使われていません。削除後は開発者ツールで「ソースマップを読み込めない」という警告が出るだけです。
sourcesContentとは何ですか?
ソースマップの任意フィールドで、元のソースコードの本文そのものを格納します。これがあると、元のコードがコメント付きでそのまま読めます。webpack・Vite・Next.jsなどでソースマップを生成すると含まれることが多い点に注意が必要です。
hidden-source-mapにすれば公開されませんか?
公開されないとは限りません。hidden設定は生成コードに参照コメントを付けないだけで、.mapファイルは出力されます。配備対象から除外しないと、main.js.mapのようにURLを推測すれば取得できます。
難読化しているので、ソースマップがあっても問題ないのでは?
ソースマップを公開すると難読化は事実上無意味になります。sourcesだけでも内部のディレクトリ構成やファイル名が分かり、sourcesContentがあれば元のコードが読めます。
エラー監視サービスでソースマップが必要な場合はどうすればよいですか?
hidden-source-mapで生成して監視サービスへアップロードし、その後に配備物から.mapを削除します。原文を含めたくない場合はsourcesContentを出さないnosources-source-mapを使います。
ソースマップの原文公開は、セキュリティAIチェッカーでどのように判定されますか?
同一オリジンのスクリプト先頭2件からソースマップ参照をたどり、sourcesContentに原文があれば「× 要改善」、ソースマップだけ取得できれば「△ 要確認」、ソースマップが取得できなければ「○ 問題なし」です。同一オリジンのJavaScriptがなければ対象外です。
ソースマップを消せば元のコードは見られなくなりますか?
圧縮されたコード自体はブラウザに配信されるため読めます。ソースマップの非公開は解析コストを上げる対策であり、APIキーなどの秘密情報をクライアントコードに置かないことが前提です。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- OWASP ASVS 5.0.0 V13 Configuration(V13.4.2)
- OWASP ASVS 5.0.0 V15 Secure Coding and Architecture(V15.2.3)
- OWASP WSTG-INFO-05 Review Web Page Content for Information Leakage
- ECMA-426 Source Map Format Specification
- MDN SourceMap header
- Next.js productionBrowserSourceMaps
- Vite Build Options(build.sourcemap)
- webpack devtool
- Vercel Changelog「Protected source maps」
- Apache HTTP Server core(FilesMatch)
- Microsoft Learn「File Name Extensions <fileExtensions>」