結論(本番HTMLにconsole.logを残していない)
本番HTMLにconsole.logを残していないとは、公開サイトのHTMLに直接書かれたスクリプトに、開発時のデバッグ出力命令 console.log( が残っていない状態です。残っていると、誰でも開発者ツールを開くだけでAPIの応答や入力値など画面に出ない情報を読めます。セキュリティAIチェッカーは、トップページのHTMLに console.log( が1件でもあれば △ 要確認(重み1)と判定し、中身の確認を促します。
この記事のポイント
- コンソールに出るのは閲覧中の本人のブラウザだけですが、攻撃者は自分の操作で出る情報をすべて観察できます。
- API応答全体、フォーム入力値、トークン、隠し機能の存在などが console.log で漏れやすい情報です。
- 診断は正規表現 console\.log\s*\( でHTML全体を検索し、1件以上で △(0.45点)、なしで ○ です。
- minifyだけでは消えません。Viteの dropConsole、Terserの drop_console、Next.jsの removeConsole を明示的に有効にします。
- ESLintの no-console ルールと納品チェックリストで再発を防ぎます。
| 診断項目名 | 本番HTMLにconsole.logを残していない |
|---|---|
| 項目ID | html.console-log |
| 分類 | 公開ファイル・情報露出 |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V13.4.2(本番環境では全構成要素のデバッグモードを無効化し、デバッグ機能や情報漏えいを防ぐ、L2)、ASVS V14.3.3(ブラウザ側に機密データを保存しない、L2)、OWASP WSTG-INFO-05、CWE-489(有効なままのデバッグコード)、CWE-532(ログへの機密情報の挿入) |
本番HTMLにconsole.logを残していないとは
本番HTMLにconsole.logを残していないとは、公開しているページのHTMLに直接書かれたスクリプトに、デバッグ用の出力命令 console.log( が残っていない状態のことです。セキュリティAIチェッカーはこの項目(html.console-log)で、トップページのHTMLに console.log( の記述が残っていないかを確認します。
console.log() は、JavaScriptの実行中に値をブラウザの開発者ツール(コンソール)へ出力するデバッグ用の命令です。開発中の動作確認には欠かせませんが、本番サイトに残したままにすると、誰でも開発者ツールを開くだけで、出力された値(APIの応答内容、利用者の入力値、内部の状態など)を読めてしまいます。
重大度は low ですが、「本番用のビルド・公開手順が整っているか」を外部から推し量る指標にもなります。
| 項目 | 内容 |
|---|---|
| 項目ID | html.console-log |
| 診断カテゴリ | 情報露出 |
| 重大度 | low |
| 重み | 1 |
| 関連標準 | OWASP ASVS 5.0.0 V13.4.2(L2)、ASVS V14.3.3(L2)、OWASP WSTG-INFO-05、CWE-489、CWE-532 |
console.logの出力は誰に見られるのか
- コンソールに表示されるのは、そのページを開いている本人のブラウザだけです。他の閲覧者の出力が攻撃者へ送られるわけではありません。
- しかし、攻撃者は自分でページを開けば、自分の操作に対して出力される情報をすべて観察できます。APIの生の応答、権限判定の途中結果、隠しパラメーターなど、画面に出ない情報が手掛かりになります。
- 共用端末(窓口の申請用端末、図書館のPC等)で、前の利用者が開いたままのタブのコンソールに、入力した個人情報が残る場合もあります。
- ブラウザ拡張機能の中にはページのコンソール出力を収集できるものがあり、出力内容が意図せず第三者に渡る経路になり得ます。
console.logで実際に漏れやすいもの
| 出力例 | 問題 |
|---|---|
console.log(response) | APIの全レスポンス。画面には一部しか表示しない個人情報や内部IDが含まれることがある |
console.log(formData) | 申請フォームの入力値(氏名、住所、電話番号) |
console.log(token) | アクセストークンやセッション情報 |
console.log('admin mode', flags) | 隠し機能や権限判定の存在 |
console.logがあっても問題ない場合
- 外部ライブラリが出す著作権表示や警告。
- 固定の文言だけを出す記述(例:「採用情報はこちら」といった開発者向けメッセージ)。
- 大規模サービスが意図的に出している「セルフXSS」への注意喚起(「ここに他人から教わったコードを貼り付けないでください」といった警告文)。利用者をだましてコンソールに不正なコードを貼り付けさせる手口への対策として、あえて
console.logを使う例があります。
このため本項目は × ではなく △ として、「中身を確認する」ことを促す設計になっています。
console.logについてよくある誤解
- 「console.logを消せばデバッグ情報は漏れない」:ネットワークタブを見ればAPIの応答はそのまま見えます。そもそもブラウザへ不要な個人情報を返さない設計(APIの応答を必要最小限にする)が本質的な対策です。
- 「minifyすれば消える」:minifyだけでは消えません。ビルドツールの「console削除」オプションを明示的に有効にする必要があります。
本番HTMLにconsole.logを残していないの診断基準(セキュリティAIチェッカー)
取得対象
- 入力URLのGET(リダイレクト最大4回追跡)で得た最終ページのHTML本文(最大2,000,000バイト、テキスト系Content-Typeのみ)。
- インラインの script 要素だけでなく、HTML全体の文字列が対象です。外部
.jsファイルの中身は読みません。
判定条件
正規表現 console\.log\s*\((大文字小文字を区別しない)がHTML本文中に1回以上現れるかを確認します。
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 一致なし | 重み1を満点で加算 |
| △ 要確認(warn) | 1件以上一致 | 重み1×0.45=0.45点 |
| (判定なし) | HTML本文を取得できない(非テキスト応答など) | 本項目は結果に出力されず、得点の分母にも入らない |
console.error、console.debug、console.infoなどは判定対象外です。最も多用され、消し忘れの指標として扱いやすいconsole.logに絞っています。- 根拠欄には「console.logの記述を確認しました。」または「インラインHTMLにconsole.logはありません。」と表示します。
誤検知の可能性
- 本文中のプログラミング解説(例:「console.log()で確認します」という文章)やコメント内の記述にも一致します。
- 外部タグ管理ツールの埋め込みコードに含まれる記述も一致します。
いずれも △(0.45点)であり、目視で内容を確認して「機密情報を出していない」と判断できれば、運用上の対応は不要な場合もあります。
自治体サイトでの判定例
| 状況 | 判定 |
|---|---|
| CMS標準テンプレートのトップページ | ○(一般的) |
委託業者が作成したスライダーやお知らせ表示のインラインスクリプトに console.log(data) が残存 | △ |
| 外部の広告・解析タグにconsole出力が含まれる | △(自組織のコードではないため、影響を確認した上で許容判断も可) |
console.logを本番に残すとどんなリスクがあるか
- 内部仕様の把握:API応答や内部状態の出力から、管理用エンドポイントや認可の仕組みが推測され、他の脆弱性を探す手掛かりになります。
- 個人情報の残存:フォーム入力値や照会結果をコンソールに出すコードは、共用端末での情報残存や、拡張機能による収集の経路になります。
- 品質管理の不備の兆候:デバッグコードが本番に残ることは、ビルド手順やレビュー体制が整っていない兆候であり、より深刻な設定漏れ(ソースマップ公開、テスト用アカウントの残存など)と同時に見つかることがあります。
- 性能への影響:大きなオブジェクトを繰り返し出力するコードは、開発者ツールを開いている環境でメモリ消費や処理遅延の原因になり、出力対象への参照が残ることで解放が遅れる場合もあります。
直接の侵害につながることは少ないため重大度は low としています。ただし「個人情報を出力している」ことが判明した場合は、本項目の重大度にかかわらず優先して修正してください。
console.logを本番で削除する方法(Vite・webpack・Next.js・CMS・ESLint)
1. 該当箇所の確認
まず、出力している値が何かを確認します。個人情報・トークン・API応答全体を出しているものは最優先で削除します。
2. ビルドツールで本番時に自動削除する
Vite(8以降。既定の圧縮はOxc)
// vite.config.js(build配下の設定は本番ビルド時のみ適用される)
export default {
build: {
rolldownOptions: {
output: { minify: { compress: { dropConsole: true, dropDebugger: true } } },
},
},
};
Vite 7以前(esbuildで圧縮)では esbuild: { drop: ['console', 'debugger'] } を使います。Vite 8ではこの esbuild オプションは非推奨です。
webpack(Terser)
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimizer: [new TerserPlugin({
terserOptions: { compress: { drop_console: true } },
})],
},
};
Next.js
// next.config.js
module.exports = {
compiler: {
removeConsole: process.env.NODE_ENV === 'production'
? { exclude: ['error', 'warn'] } // エラーと警告だけ残す
: false,
},
};
3. ビルド工程がない(CMS・手書きHTML)場合
- インラインスクリプトから
console.logの行を削除します。 - 開発時のログを残したい場合は、フラグで出力を切り替える小さな関数を用意します。
<script>
const DEBUG = false; // 本番はfalse
const log = (...args) => { if (DEBUG) console.log(...args); };
log('お知らせ件数', items.length);
</script>
ただし、この方法でも文字列としての console.log はHTMLに残るため、本診断では △ のままです。完全に解消するには、関数を外部 .js ファイルへ移すか、本番では呼び出しごと削除してください。
4. Lintで再発防止
ESLintの no-console ルールを有効にし、委託先の納品基準に含めます(ESLint 10以降は eslint.config.js のみ有効で、旧 .eslintrc は読み込まれません)。
// eslint.config.js
export default [
{ rules: { 'no-console': ['error', { allow: ['warn', 'error'] }] } },
];
5. 外部JavaScriptも含めて点検する
本診断はトップページのHTMLだけを見ますが、実際には外部 .js ファイルや下層ページのスクリプトにも同じ問題が残りがちです。ビルド成果物やCMSのテーマディレクトリをまとめて検索すると効率的です。
# ビルド成果物(dist、.next/static等)やテーマ内のconsole.logを一覧
grep -rn --include='*.js' --include='*.html' --include='*.php' 'console\.log' ./dist ./wp-content/themes/mytheme
検出された箇所を「固定文言のみ」「変数を出力」「個人情報・トークン・API応答を出力」に分類し、後者から順に削除します。
6. 委託・納品時のチェック項目にする
委託開発では、仕様書や納品検査のチェックリストに「本番用ビルドでデバッグ出力(console.log、debugger文、ソースマップ)を除去していること」を明記すると、発注側でも確認しやすくなります。「ソースマップ参照を公開していない」と同時に点検すると効率的です。
確認方法
curl -s https://www.city.example.lg.jp/ | grep -n 'console\.log'
ブラウザでは、開発者ツール(F12)の「Console」タブを開いた状態でページを再読み込みし、自組織のスクリプトから出力がないことを確認します。修正後はセキュリティAIチェッカーで再診断し、本項目が ○ になったことを確認します。
サイトを壊さないための注意点(ガードレール)
drop_console等で一括削除する際、console.log(処理())のように引数内で必要な処理を呼んでいるコードは、その処理ごと消えて動作が変わる可能性があります。削除後に主要な画面操作をテストしてください。- エラー監視のために
console.errorを残す運用は一般的です。削除対象はconsole.log等のデバッグ出力に絞ると安全です。
よくある質問(FAQ)
console.logを本番に残すと、他の利用者の情報が見られてしまいますか?
コンソールに表示されるのは、そのページを開いている本人のブラウザだけで、他の閲覧者の出力が攻撃者へ送られるわけではありません。ただし攻撃者は自分の操作に対する出力をすべて観察できるほか、共用端末に開いたままのタブや、コンソール出力を収集できるブラウザ拡張機能が情報の残存・流出経路になり得ます。
minifyすればconsole.logは消えますか?
minifyだけでは消えません。Vite 8なら rolldownOptions の minify で dropConsole、webpackならTerserの drop_console、Next.jsなら compiler.removeConsole のように、console削除のオプションを明示的に有効にする必要があります。
console.errorやconsole.warnも診断対象ですか?
対象外です。最も多用され、消し忘れの指標として扱いやすい console.log に絞って判定しています。エラー監視のために console.error を残す運用は一般的です。
本番HTMLのconsole.logは、なぜ × ではなく △ 判定なのですか?
外部ライブラリの警告、固定文言だけの開発者向けメッセージ、セルフXSSへの注意喚起など、console.log があっても問題ない場合があるためです。△ として、出力している中身を確認することを促しています。
DEBUGフラグで出力を止めれば △ は解消しますか?
解消しません。フラグで出力を止めても console.log という文字列はHTMLに残るため、診断は △ のままです。完全に解消するには、その関数を外部 .js ファイルへ移すか、本番では呼び出しごと削除します。
本文中の解説文の「console.log()」でも △ になりますか?
なります。本文中のプログラミング解説やコメント内の記述、外部タグ管理ツールの埋め込みコードにも一致します。目視で内容を確認し、機密情報を出していないと判断できれば、運用上の対応は不要な場合もあります。
drop_consoleで一括削除するときの注意点は?
console.log(処理()) のように引数内で必要な処理を呼んでいるコードは、その処理ごと消えて動作が変わる可能性があります。削除後に主要な画面操作をテストしてください。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- OWASP ASVS 5.0.0 V13 Configuration
- OWASP ASVS 5.0.0 V14 Data Protection
- OWASP WSTG-INFO-05 Review Web Page Content for Information Leakage
- MDN console.log()
- Next.js compiler removeConsole
- Vite Migration from v7(esbuild.dropの移行先)
- Oxc Minifier Dead Code Elimination(dropConsole)
- esbuild drop
- ESLint no-console