• 診断項目 No.28/127
  • 公開ファイル・情報露出
  • 重大度 低(low)

本番HTMLにconsole.logを残していないとは?消し忘れのリスク・診断基準・削除方法

本番HTMLにconsole.logを残していないとは、公開ページのスクリプトにデバッグ出力が残っていない状態です。漏れやすい情報、Vite・webpack・Next.jsでの自動削除、ESLintでの再発防止、診断基準を解説します。

結論(本番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を残していない
項目IDhtml.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 ですが、「本番用のビルド・公開手順が整っているか」を外部から推し量る指標にもなります。

項目内容
項目IDhtml.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(処理()) のように引数内で必要な処理を呼んでいるコードは、その処理ごと消えて動作が変わる可能性があります。削除後に主要な画面操作をテストしてください。

セキュリティAIチェッカーを利用する

この項目を含む127項目を、URLを入れるだけで無料診断します。

参考資料