結論(外部iframeのsandbox)
外部iframeのsandboxとは、外部オリジンのページを埋め込むiframe要素にsandbox属性を付け、権限を絞る設定です。スクリプト実行・フォーム送信・ポップアップ・最上位ページの遷移などを既定ですべて禁止し、必要な権限だけをallow-*トークンで戻します。埋め込み先が侵害されても、公式サイトを偽サイトへ遷移させるなどの被害を抑えられます。セキュリティAIチェッカーは、外部iframeすべてにsandboxがあれば○、1つでも無ければ△と判定します。
この記事のポイント
- sandbox属性は値を空にするとすべての制限を適用し、allow-scriptsなどのトークンで個別に解除します。
- OWASP HTML5 Security Cheat Sheetは、信頼できないコンテンツにはsandboxを使い、追加の防御層として扱うよう推奨しています。
- 同一オリジンのiframeでallow-scriptsとallow-same-originを併用すると、sandboxを取り除けるため防御になりません。
- allow-top-navigationとallow-popups-to-escape-sandboxは、必要性が確認できた場合に限り付けます。
- CSPのframe-srcで埋め込みを許可する配信元を限定すると、属性の付け忘れを補えます。
- 診断対象は外部オリジンのiframeだけで、1つも無ければ対象外です。allow-*の中身は自動判定しません。
| 診断項目名 | 外部iframeのsandbox |
|---|---|
| 項目ID | html.iframe-sandbox |
| 分類 | HTML・JavaScript・外部資産 |
| 重大度・配点の重み | 中(medium) 重み 2 |
| 関連する標準・ガイドライン | OWASP HTML5 Security Cheat Sheet「Sandboxed frames」(信頼できないコンテンツにはiframeのsandbox属性を使う)/OWASP WSTG-CLNT-06「Client-side Resource Manipulation」、WSTG-CLNT-11「Web Messaging」(埋め込み先との連携の確認)/HTML Living Standard iframe要素のsandbox属性/CWEは特定の対応なし(多層防御の設定項目) |
外部iframeのsandboxとは
外部iframeのsandboxとは、外部オリジン(自サイトとスキーム・ホスト・ポートのいずれかが異なる配信元)のページを埋め込む <iframe> 要素に sandbox 属性を付け、埋め込んだコンテンツができることを最小限に制限する設定です。
<iframe src="https://widget.example.jp/info" title="お知らせ" sandbox></iframe>
自治体の公式サイトでは、YouTubeの動画、Googleマップなどの地図、SNSのタイムライン、外部の施設予約・アンケートシステム、天気・防災情報ウィジェットなどを <iframe> で埋め込むことがよくあります。iframeの中身は外部事業者が管理しており、自庁ではコントロールできません。その事業者側が侵害されたり、広告配信網経由で不正なコンテンツが混入したりすると、iframeの中から次のような動作が起こり得ます。
- 公式サイトのページ全体を別サイトへ遷移させる
- ポップアップを出す
- フォームを表示して情報を入力させる
sandbox 属性は、iframe内のコンテンツに対して「スクリプト実行」「フォーム送信」「ポップアップ」「最上位ページの遷移」などを既定ですべて禁止し、必要な権限だけを allow-* トークンで個別に戻す仕組みです。セキュリティAIチェッカーのこの項目は、トップページに埋め込まれた外部オリジンのiframeにsandbox属性が付いているかを確認します。
iframeのsandbox属性はどう動くのか
空のsandboxはすべてを制限し、トークンで解除する
MDNによると、sandbox 属性は値を空にするとすべての制限を適用し、空白区切りのトークンで個別に制限を解除します。主なトークンは次のとおりです。
| トークン | 解除される制限 |
|---|---|
allow-scripts | スクリプトの実行 |
allow-same-origin | 本来のオリジンとしての扱い(無いと常に同一オリジンポリシーに失敗する特別なオリジンになる) |
allow-forms | フォーム送信 |
allow-popups | window.open() や target="_blank" による新しいウィンドウ |
allow-popups-to-escape-sandbox | 開いたウィンドウにsandboxを引き継がない |
allow-presentation | プレゼンテーションセッションの開始 |
allow-top-navigation-by-user-activation | ユーザー操作を伴う場合のみ最上位ページの遷移 |
allow-top-navigation | 最上位ページの遷移(無条件) |
allow-downloads | ファイルのダウンロード |
allow-modals | alert() 等のモーダル表示 |
OWASPのHTML5 Security Cheat Sheetは、信頼できないコンテンツにはiframeのsandbox属性を使うこと、sandboxは追加の防御層として扱うことを推奨しています。sandbox属性の仕様はHTML Living Standardのiframe要素で定義されています。特定のCWEには対応しない、多層防御のための設定項目です。
allow-scriptsとallow-same-originの組み合わせに注意
MDNは、埋め込むドキュメントが親ページと同一オリジンの場合に allow-scripts と allow-same-origin を同時に指定することを強く非推奨としています。同一オリジンのスクリプトは親ページのDOMから自分のsandbox属性を取り除けるため、sandboxが無いのと同じになるからです。
一方、外部オリジンのiframeでは親のDOMにアクセスできないため、動画プレーヤーのように両方が必要な埋め込みでも、それ以外の権限(最上位遷移、無制限のポップアップ等)を絞る効果は残ります。
sandboxと一緒に使う関連属性
allow属性:カメラ、位置情報、全画面表示などのブラウザ機能をPermissions Policyで制限します。MDNによると、allow属性はPermissions-Policyヘッダーの上に追加で制限をかけるもので、ヘッダーを置き換えるものではありません。ヘッダー側の設定は「Permissions-Policy」の項目で確認します。referrerpolicy属性:埋め込み先へ送るReferer情報を制御します(既定はstrict-origin-when-cross-origin)。サイト全体の方針は「Referrer-Policy」の項目で確認します。
なお、この項目は「自サイトが外部のページを埋め込む」ときの制限です。逆に「自サイトが他人のページに埋め込まれる」ことを防ぐのは「クリックジャッキング対策」、埋め込み先とのメッセージのやり取りは「postMessageの送受信元を限定」で扱います。OWASP WSTGでは、WSTG-CLNT-06「Client-side Resource Manipulation」とWSTG-CLNT-11「Web Messaging」が埋め込み先との連携の確認に当たります。
外部iframeのsandboxについてよくある誤解
- 「sandboxを付けると埋め込みが必ず壊れる」:必要なトークンを付ければ動作する埋め込みも多くあります。ただし事業者ごとに必要な権限が異なるため、必ず実機で確認します。
- 「自庁サーバー上のページを埋め込む場合もsandboxが必要」:同一オリジンのiframeに
allow-scripts allow-same-originを付けても上記の理由で防御になりません。同一オリジンの場合は埋め込むページ自体の安全性を確保します。本項目も外部オリジンのiframeだけを対象にしています。
外部iframeのsandboxの診断基準(セキュリティAIチェッカー)
取得対象
- 診断URLへのGETで取得したトップページ(最終URL)のHTML本文(最大2MB)。
- JavaScriptで後から生成されるiframe(遅延読み込みで
data-srcからsrcへ差し替える方式など)は対象外です。
判定手順
<iframe ...>タグをすべて抽出します。- 各タグの
src属性(data-src等の独自属性は除外)を最終URLを基準に解決し、スキームがhttp/httpsで、オリジンが最終URLのオリジンと異なるものを「外部iframe」とします。srcが無いもの、srcdocのみのもの、about:blank、同一オリジンのものは対象外です。 - 外部iframeの属性文字列に、独立した
sandbox属性((?:^|\s)sandbox(?=\s|=|\/|$)。値なしのsandboxも含む)があるかを確認します。data-sandboxのような独自属性は数えません。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | すべての外部iframeにsandbox属性がある | 重み2を満点で加算 |
| △ 要確認(warn) | sandbox属性のない外部iframeが1つ以上ある(根拠欄に「sandboxなし: 件数/外部iframe総数」) | 2×0.45=0.9点 |
| × 要改善(fail) | 使用しない(sandboxは多層防御であり、無いこと自体は脆弱性の確定ではないため) | — |
| 対象外(na) | 外部オリジンのiframeが1つもない | 得点計算から除外 |
sandboxに付けた allow-* トークンの内容(権限が広すぎないか)は自動判定していません。○であっても、各埋め込みの権限が必要最小限かは台帳で確認してください。
自治体サイトでの判定例
| トップページの状態 | 判定 |
|---|---|
YouTubeの <iframe src="https://www.youtube.com/embed/..."> があり、sandboxなし | △(sandboxなし: 1/1件) |
| Googleマップと防災ウィジェットの2つを埋め込み、両方にsandboxあり | ○ |
自庁サーバーの /map/index.html だけをiframeで表示 | 対象外(外部iframeが無いため) |
| iframeを一切使っていない | 対象外 |
外部iframeにsandboxが無いとどんなリスクがあるか
攻撃シナリオ(ウィジェット提供事業者が侵害された場合)
- 公式サイトのトップページに、外部事業者が提供するイベント情報ウィジェットがsandboxなしで埋め込まれている。
- 事業者のサーバーが侵害され、ウィジェットに
top.location = 'https://偽サイト.example/'のようなスクリプトが混入する。 - ウィジェット内をクリックまたはタップした住民は、画面全体が自治体を装った偽サイトへ遷移したことに気付かず、給付金申請を装ったフォームに個人情報を入力してしまう。Chromeなどは、利用者が一度も操作していない外部オリジンのiframeからの最上位遷移を制限していますが、操作後の遷移は止められません。
sandboxで allow-top-navigation を付けていなければ、手順3の最上位ページの遷移はブラウザで阻止されます。
想定される被害
- 公式サイトを起点としたフィッシングサイトへの誘導
- 不要なポップアップや自動ダウンロードによる住民の端末被害
- 埋め込み先の不具合や侵害が、公式サイト全体の信頼性低下につながる
住民から見れば、iframeの中身が外部事業者のものであっても「市のサイトで起きたこと」です。自庁が管理できない領域だからこそ、できることを最小限にしておく意味があります。
外部iframeにsandboxを設定する方法(HTML・Apache・nginx・IIS・Next.js)
1. 埋め込みの棚卸し
curl -s https://www.city.example.lg.jp/ | grep -oiE '<iframe[^>]*>'
grep -rnoiE '<iframe[^>]*>' ./templates ./htdocs | grep -vi sandbox
埋め込み先ごとに、事業者・用途・必要な機能(再生、全画面、地図操作、フォーム送信など)を台帳にまとめます。
2. 最小権限のsandboxを付与
用途ごとに、必要なトークンだけを付けます。
<!-- 動画プレーヤー(再生・全画面に必要な権限の例。実機で確認すること) -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
title="市長メッセージ動画"
sandbox="allow-scripts allow-same-origin allow-presentation allow-popups"
allow="fullscreen; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
loading="lazy"></iframe>
<!-- 表示だけでよい静的ウィジェット -->
<iframe src="https://widget.example.jp/info" title="お知らせ" sandbox></iframe>
<!-- 外部フォーム(送信が必要) -->
<iframe src="https://form.example.jp/survey" title="アンケート"
sandbox="allow-scripts allow-same-origin allow-forms"></iframe>
allow-top-navigation と allow-popups-to-escape-sandbox は、必要性が確認できた場合に限り付けます。
3. サーバー側の補完設定(CSPのframe-src)
iframe属性の付け忘れに備え、CSPの frame-src で埋め込みを許可する配信元を限定します。
Apache(.htaccess)
# Apache (.htaccess)
<IfModule mod_headers.c>
Header always set Content-Security-Policy-Report-Only "frame-src https://www.youtube.com https://www.google.com"
</IfModule>
nginx
add_header Content-Security-Policy-Report-Only "frame-src https://www.youtube.com https://www.google.com" always;
IIS(web.config)
<!-- IIS web.config -->
<add name="Content-Security-Policy-Report-Only" value="frame-src https://www.youtube.com https://www.google.com" />
Next.js(Vercel)・CMS
Next.js(Vercel)ではJSXで <iframe sandbox="allow-scripts allow-same-origin" ... /> のように記述でき、CSPは next.config.js の headers() で付与します。CMSでは、記事本文に埋め込みコードを貼る運用の場合、テンプレート側の埋め込み部品(ショートコード等)でsandboxを自動付与すると付け忘れを防げます。
4. 確認方法
- 開発者ツールのコンソールに「Blocked script execution in ... because the document's frame is sandboxed」等のメッセージが出ていないか、埋め込みごとに再生・操作・送信を試します。
curl -s URL | grep -oiE '<iframe[^>]*>' | grep -vci sandboxが0になることを確認します。- 本診断を再実行し、○(pass)になることを確認します。
サイトを壊さないための注意点
- 空の
sandboxを一律に付けると、動画が再生できない、地図が操作できない等の不具合が起きます。埋め込み先ごとに必要なトークンを確認してから反映します。 - 同一オリジンのページを埋め込む場合、
allow-scripts allow-same-originの組み合わせは防御にならないため、sandboxに頼らずページ自体を安全に保ちます。 frame-srcを強制モードにする前に、Report-Onlyで既存の埋め込みが漏れなく許可されているかを確認します。
よくある質問(FAQ)
iframeにsandboxを付けるとYouTube動画は再生できなくなりますか?
空のsandboxを付けると再生できなくなる可能性があります。必要なトークンを付ければ動作する埋め込みも多く、例ではallow-scripts allow-same-origin allow-presentation allow-popupsを指定しています。事業者ごとに必要な権限が異なるため、必ず実機で確認してください。
allow-scriptsとallow-same-originを両方付けると危険ですか?
埋め込むページが親ページと同一オリジンの場合、MDNはこの組み合わせを強く非推奨としています。スクリプトが親のDOMから自分のsandbox属性を取り除けるためです。外部オリジンのiframeでは親のDOMにアクセスできないため、他の権限を絞る効果は残ります。
自庁サーバーのページをiframeで表示する場合もsandboxが必要ですか?
本項目の対象は外部オリジンのiframeだけで、同一オリジンのものは対象外です。同一オリジンではallow-scripts allow-same-originを付けても防御にならないため、埋め込むページ自体の安全性を確保します。
sandboxとallow属性の違いは何ですか?
sandboxはスクリプト実行・フォーム送信・ポップアップ・最上位遷移などを制限します。allow属性はカメラ・位置情報・全画面表示などのブラウザ機能をPermissions Policyで制限するもので、Permissions-Policyヘッダーの上に追加で制限をかけます。
sandboxが無いと×(要改善)になりますか?
なりません。sandboxは多層防御であり、無いこと自体は脆弱性の確定ではないため、外部iframeにsandboxが無い場合は△(重み2×0.45=0.9点)です。外部iframeが1つも無ければ対象外です。
JavaScriptで後から生成するiframeは診断されますか?
されません。トップページのHTMLに書かれたiframeタグのsrc属性だけを対象にしており、data-srcからsrcへ差し替える遅延読み込みなど、JavaScriptで後から生成されるiframeは確認していません。
この項目を含む127項目を、URLを入れるだけで無料診断します。