結論(外部JavaScript依存数)
外部JavaScript依存数とは、Webページが script 要素の src で別オリジン(スキーム・ホスト・ポートのいずれかが異なる配信元)から読み込んでいるJavaScriptの件数です。外部スクリプトは自サイトのスクリプトと同じ権限で動くため、件数が増えるほど配信元の侵害やドメイン譲渡の影響を受ける経路が増えます。セキュリティAIチェッカーは、トップページで5件以下なら○、6件以上なら△と判定します。
この記事のポイント
- 外部スクリプトは、読み込んだページのDOM・フォーム入力・HttpOnlyでないCookie・localStorageにアクセスできます。
- 件数そのものは脆弱性ではありませんが、監視・契約・更新管理の対象が増え、棚卸しの必要性を示す指標になります。
- 2024年のpolyfill.ioの事例では、サイト側が何も変更していなくても配信元の改変で被害を受けました。
- 判定はHTMLに直接書かれた外部scriptの件数で、5件以下が○、6件以上が△です。5件は運用上の目安です。
- 台帳化、不要タグの削除、自己ホスト、iframe化、CSPによる配信元限定で依存を減らします。
| 診断項目名 | 外部JavaScript依存数 |
|---|---|
| 項目ID | html.external-scripts |
| 分類 | HTML・JavaScript・外部資産 |
| 重大度・配点の重み | 中(medium) 重み 2 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V3.6.1(L3: 外部ホストの資産は静的・版固定かつSRI付きに限る)/OWASP Third Party JavaScript Management Cheat Sheet/CWE-829(信頼できない制御領域からの機能の取り込み) |
外部JavaScript依存数とは
外部JavaScript依存数とは、Webページが <script src="https://別のオリジン/..."> の形で、別のオリジンから読み込んでいるJavaScriptの件数です。
外部から読み込まれたJavaScriptは、自治体サイトのページ上で、自治体自身のスクリプトと同じ権限で動作します。アクセス解析、タグマネージャー、翻訳・読み上げ・文字拡大などのアクセシビリティ支援、地図、SNS埋め込み、チャットボット、CDNから読み込むライブラリなどが該当します。
外部スクリプトが1つ増えるごとに、その配信元が侵害されたり、ドメインの所有者が変わったりしたときに自治体サイトが影響を受ける経路が1つ増えます。セキュリティAIチェッカーのこの項目は、トップページで読み込まれている外部JavaScriptの件数を数え、依存が過大でないかを確認します。
「外部」の定義(オリジンが異なるもの)
この項目では、スクリプトURLのオリジン(スキーム・ホスト・ポート)がページのオリジンと異なるものを外部とします。www.city.example.lg.jp のページから cdn.city.example.lg.jp を読み込む場合も、オリジンが異なるため外部として数えます。自治体が管理するサブドメインであれば、台帳上は「自組織管理」として区別して管理するとよいでしょう。
外部JavaScriptの依存数がなぜ重要なのか
外部スクリプトに与えている権限
ブラウザの同一オリジンポリシーは「どこから読み込んだか」ではなく「どのページで実行されたか」で権限を決めます。外部スクリプトは読み込んだページのDOM、フォーム入力、同一オリジンのAPI、HttpOnly でないCookie、localStorage にアクセスできます。OWASP Third Party JavaScript Management Cheat Sheetは、主要なリスクとして次の3つを挙げています。
- 管理の喪失:第三者のコードはいつでも変更されうる
- 任意コード実行:ベンダーのサーバーが侵害されると、利用する全サイトに悪性コードが注入される
- データ漏えい:ブラウザが第三者サーバーに直接接続し、ヘッダーやリファラー等を送る
件数を見る意味
件数そのものは脆弱性ではありませんが、外部スクリプトはそれぞれが独立した供給元であり、監視・契約・更新管理の対象が増えます。件数が多いサイトでは「誰が何のために入れたか分からないタグ」が残っていることが多く、棚卸しの必要性を示す指標になります。
なお、タグマネージャー経由で後から追加されるスクリプトは、最初のHTMLには現れません。この項目の件数は「HTMLに直接書かれた外部スクリプト」の数であり、実際の依存数はこれより多い可能性があります。
関連する診断項目との住み分け
この項目は「件数」だけを見ます。配信元ドメイン数は「外部スクリプト配信元を限定」、改ざん検知は「外部JavaScriptのSRI」、latest 指定や配信元のリダイレクトは「外部資産のバージョン固定」で評価します。
外部JavaScript依存数の診断基準(セキュリティAIチェッカー)
取得対象
- 入力URLのリダイレクト後の最終URLのHTML本文(最大2MB)を対象にします。
<script ... src="...">形式の要素(属性値は引用符で囲まれたもの)を数えます。srcはページURLを基準に絶対URLへ解決し、オリジンを比較します。解決できないURLは数えません。- 同じURLが複数回書かれている場合は、書かれた回数だけ数えます。HTMLコメント内の記述も文字列として数えます。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 外部JavaScriptが5件以下(0件を含む) | 重み2を満点で加算 |
| △ 要確認(warn) | 外部JavaScriptが6件以上 | 重み2×0.45 |
- この項目に×(fail)と対象外(na)はありません。外部スクリプトが0件のサイトも○になります。
- 5件という閾値は、一般的な自治体サイトの構成(アクセス解析、タグマネージャー、アクセシビリティ支援、地図程度)を許容しつつ、依存が膨らんだ状態を検知するための運用上の目安です。標準規格に定められた数値ではありません。
- 根拠欄には「外部JavaScriptを○件確認しました。」と件数を表示します。重大度はmedium、重みは2です。
自治体サイトでの判定例
| 外部スクリプトの構成 | 件数 | 判定 |
|---|---|---|
| アクセス解析(gtag.js)、タグマネージャー、翻訳ウィジェット、読み上げ支援 | 4 | ○ |
| 上記に加え、SNS埋め込み3種、地図API、チャットボット、jQuery(CDN)、スライダー(CDN) | 11 | △ |
| すべてのスクリプトを自サイトから配信 | 0 | ○ |
検出の限界
- タグマネージャーや他のスクリプトが実行時に追加する
script要素は数えません。トップページで○でも、ブラウザで実際に読み込まれる外部スクリプトはこれより多いことがあります。 - 属性値を引用符で囲まない
src=https://...の記述は数えません。 data-srcのように同意取得後に読み込むための属性も、文字列としてsrc=に一致するため数える場合があります。これは同意後に実際に読み込まれる依存先であるため、台帳管理の対象とする扱いで差し支えありません。- 件数は「多いか少ないか」の目安であり、個々のスクリプトの安全性(版固定、SRI、配信元の信頼性)は関連項目で評価します。
個々の外部スクリプトを評価する観点
| 観点 | 確認内容 |
|---|---|
| 目的 | 何のために必要か。代替手段(自己ホスト、iframe、リンク)はないか |
| 配信元 | 契約関係のある事業者か。ドメインの管理者は誰か |
| 版管理 | 版が固定されているか。更新時に誰が確認するか |
| 完全性 | SRIを付けられるか。付けられない場合の補完策は何か |
| 送信データ | ページURL、Cookie、入力値など、何が第三者へ送られるか |
| 掲載範囲 | 全ページで必要か、特定ページだけでよいか |
外部JavaScriptへの依存が多いとどんなリスクがあるか
- サプライチェーン攻撃:
polyfill.ioのドメインと配信サービスは2024年2月に第三者へ売却され、その後cdn.polyfill.ioから配信されるスクリプトが改変されて、モバイル端末の利用者が無関係な外部サイトへ転送されるようになったと、Sansecが2024年6月に報告しました。このスクリプトを埋め込んでいたサイトは10万を超えるとされています。サイト側は何も変更していなくても被害を受けた事例です。 - 決済・個人情報の窃取:英国ICOは2020年、2018年にTicketmasterの決済ページに置かれた第三者(Inbenta)のチャットボットのスクリプトが悪用され、カード情報などが流出した件で、Ticketmasterに125万ポンドの制裁金を科しました。外部スクリプトが入力内容にアクセスできることを示す事例です。
- 意図しない利用者情報の送信:外部スクリプトはページURL、閲覧情報、場合によってはフォーム入力を第三者へ送信できます。子育てや福祉など機微な相談ページで外部タグが動くと、閲覧の事実が第三者に記録されます。
- 可用性:外部サービスの障害や提供終了で、ページの表示やメニュー操作が止まることがあります。
外部JavaScript依存数を減らす方法(棚卸し・自己ホスト・CSP)
1. 棚卸しと台帳化
# トップページの外部スクリプトを一覧化
curl -s https://www.city.example.lg.jp/ \
| grep -o -i -E '<script[^>]*src="(https?:)?//[^"]+"' \
| sed -E 's/.*src="([^"]+)".*/\1/' | sort | uniq -c
各スクリプトについて、目的、担当課、契約・利用規約、送信されるデータ、導入日、見直し期限を台帳に記録します。目的が説明できないものは削除候補です。
2. 削減の方針
| 種類 | 対応 |
|---|---|
| CDNのライブラリ(jQuery等) | 版を固定して自サイトから配信する(自己ホスト) |
| 使われていない旧キャンペーン用タグ | 削除 |
| SNS埋め込みスクリプト | 必要なページだけに限定する、またはリンクに置き換える |
| 重複している解析タグ | タグマネージャーか直接設置かのどちらかに統一 |
| チャットボット・地図 | iframe形式(別オリジン)で埋め込み、親ページにスクリプトを入れない方式を優先 |
OWASPのチートシートも、ベンダースクリプトをサンドボックス化したiframeに隔離する方法や、自己ホストを推奨しています。
3. 自己ホストの例
<!-- 変更前 -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- 変更後: 同じファイルを自サイトに置き、版をファイル名に含める -->
<script src="/assets/vendor/jquery-3.7.1.min.js" defer></script>
自己ホストにした場合、そのライブラリの脆弱性情報の確認と更新は自組織の責任になります。
4. CSPで読み込み元を限定
Apache(.htaccess)
<IfModule mod_headers.c>
Header always set Content-Security-Policy-Report-Only "script-src 'self' https://www.googletagmanager.com; object-src 'none'; base-uri 'self'"
</IfModule>
nginx
add_header Content-Security-Policy-Report-Only "script-src 'self' https://www.googletagmanager.com; object-src 'none'; base-uri 'self'" always;
IIS(web.config)
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy-Report-Only" value="script-src 'self' https://www.googletagmanager.com; object-src 'none'; base-uri 'self'" />
</customHeaders>
</httpProtocol>
Next.js(next.config.js)
module.exports = {
async headers() {
return [{ source: "/(.*)", headers: [{ key: "Content-Security-Policy-Report-Only",
value: "script-src 'self' https://www.googletagmanager.com; object-src 'none'; base-uri 'self'" }] }];
},
};
CSPの全体設計は「Content Security Policy」で解説しています。
5. サイトを壊さないための注意点
- インラインスクリプトやイベント属性が多いCMSでは、
script-srcを強制すると多くの機能が止まります。必ずReport-Onlyで違反を収集し、許可対象を確定してから強制に切り替えてください。 - タグマネージャー経由で読み込むスクリプトは、CSPの許可リストにも追加が必要です。
- スクリプトを削除するときは、依存する機能(メニュー、検索、文字サイズ変更等)の動作を、PCとスマートフォンの両方で確認します。
6. 確認方法
ブラウザの開発者ツール「ネットワーク」タブで種類「JS」に絞り、ドメインごとに並べて、HTMLに書かれていないタグマネージャー経由のスクリプトも含めて把握します。整理後はセキュリティAIチェッカーで再診断し、根拠欄の件数が減ったことを確認してください。
よくある質問(FAQ)
外部JavaScriptは何件までなら問題ありませんか?
セキュリティAIチェッカーでは、トップページのHTMLに直接書かれた外部JavaScriptが5件以下なら○、6件以上なら△です。5件はアクセス解析・タグマネージャー・アクセシビリティ支援・地図程度の構成を許容する運用上の目安で、標準規格の数値ではありません。
同じ自治体が管理するサブドメインから読み込む場合も外部に数えますか?
数えます。www.city.example.lg.jp のページから cdn.city.example.lg.jp を読み込む場合もオリジンが異なるため外部です。台帳上は「自組織管理」として区別して管理するとよいでしょう。
タグマネージャー経由で読み込むスクリプトも数えられますか?
数えられません。実行時に追加される script は最初のHTMLに現れないため、実際の依存数は診断の件数より多い可能性があります。ブラウザの開発者ツールのネットワークタブで、種類「JS」に絞って確認してください。
外部スクリプトを自己ホストにすれば安全ですか?
配信元の侵害やドメイン譲渡の影響は受けなくなりますが、そのライブラリの脆弱性情報の確認と更新は自組織の責任になります。版をファイル名に含めて管理してください。
外部スクリプトが0件でも○になりますか?
なります。この項目には×と対象外がなく、0件も含めて5件以下はすべて○です。
外部JavaScriptのSRIや配信元の数は別に評価されますか?
はい。改ざん検知は「外部JavaScriptのSRI」、配信元のホスト数は「外部スクリプト配信元を限定」、latest指定や配信元のリダイレクトは「外部資産のバージョン固定」で評価します。
この項目を含む127項目を、URLを入れるだけで無料診断します。