iframe sandbox:各トークンで許可される動作
iframeのsandbox属性
iframe sandbox:全トークンをライブ切り替えデモで解説 | We.Inc
iframe sandboxの各トークンをオン・オフして、スクリプト、フォーム、ポップアップ、アラートが動いたり止まったりする様子を確認できます。全トークンを解説します。
空のsandbox属性はiframeを強力に制限します。スクリプトもフォーム送信もポップアップもアラートも使えず、オリジンは不透明になってすべての同一オリジンチェックに失敗します。allow-トークンを1つ追加するごとに、機能が1つずつ戻ります。下のトークンを切り替えて何が動かなくなるかを正確に確認し、埋め込みに必要な最小限の組み合わせをコピーしましょう。
よくある用途と必要なトークン
- 自分で生成した静的HTMLのプレビュー
- sandbox(空)
- インタラクティブなデモやコードプレイグラウンドの出力
- sandbox="allow-scripts"
- 回答を送信するサードパーティのフォーム
- sandbox="allow-scripts allow-forms allow-same-origin"(別オリジンの場合のみ)
- リンクを新しいタブで開くウィジェット
- allow-popups allow-popups-to-escape-sandbox を追加
- マウスをキャプチャするゲーム
- allow-pointer-lock を追加
sandbox属性は、自分が書いていないコンテンツ(ユーザーのHTML、広告枠、生成したページのプレビューなど)を表示するiframeに追加できる、最も手軽なセキュリティ対策です。難しいのは、ある埋め込みにどのトークンが必要かを見極めることです。トークンが足りなくても、たいていは何のエラーも出ずに失敗するからです。下のライブフレームでは実際のテストが動くので、推測せずに各失敗を目で確認できます。埋め込みの基本については、HTMLのiframeと動画のガイドから始めてください。
- リストのトークンにチェックを入れます。右側のフレームがそのsandbox値で再読み込みされ、その値はフレームの上にコピーできるコードとして表示されます。
- allow-scriptsがオフのときは、内部で何も実行できないため、フレームには代替メッセージだけが表示されます。
- allow-scriptsをオンにすると、フレームが自身のオリジンを表示し、フォーム送信、ポップアップを開く、アラート表示のボタンが現れます。
- 各ボタンは、ブラウザーがその操作を許可したかどうかを表示します。対応するトークンを追加してもう一度押し、結果を比べてみましょう。
- 空のsandboxから始めて、埋め込みが動くまでトークンを1つずつ追加しましょう。長いリストから削っていくほうが、考えるのが難しくなります。
- 自分のオリジンから配信するコンテンツでは、allow-scriptsとallow-same-originを決して組み合わせないでください。フレーム内のページが自分でsandboxを外せてしまいます。
- ユーザーが書いたHTMLにはsrcdocか別のサブドメインを使いましょう。そうすれば、トークンの設定を間違えてもメインサイトのCookieには届きません。
- sandbox自体は、カメラやマイクなどの機能を制限しません。権限ポリシーにはallow属性を併用してください。
- フレーム内のリンクを通常のタブで開く必要がある場合は、allow-popups-to-escape-sandboxを追加してください。追加しないと、新しいタブにも同じ制限が引き継がれます。
よくある質問
空のsandbox属性は何をしますか?
すべての制限を一度に適用します。フレーム内のドキュメントは、スクリプトの実行、フォームの送信、ポップアップやモーダルを開くこと、トップウィンドウの遷移、ポインターや画面の向きのロック、ダウンロードの開始ができなくなり、どこにも一致しない一意のオリジンから来たものとして扱われます。
allow-scriptsとallow-same-originの組み合わせはなぜ危険なのですか?
フレーム内のドキュメントがあなたのページと同じオリジンにある場合、この2つのトークンがそろうと、そのスクリプトが親側に手を伸ばしてsandbox属性を削除できます。結果として、普通のiframeと同じ安全性しかなくなります。本当に別のオリジンから来るコンテンツなら、そもそもあなたのページに触れられないので、この組み合わせでも問題ありません。
sandbox内のフォームで送信を押しても何も起きません。なぜですか?
allow-formsがないと、フォームは表示されますが、送信しても検証は行われず、サーバーにデータも送られません。allow-formsを追加してください。フォームが自サイトのCookieやストレージにも依存している場合は、allow-same-originも必要です。
sandbox化したiframeがページ全体をリダイレクトすることはありますか?
allow-top-navigationか、ユーザーがフレーム内をクリックした後にだけ許可するallow-top-navigation-by-user-activationを追加しない限り、できません。両方を外しておけば、埋め込みがあなたのページを別のサイトに置き換えることを防げます。
信頼できないHTMLを安全に表示するにはsandboxだけで十分ですか?
sandboxは主要な防御層ですが、唯一の層ではありません。信頼できないコンテンツは別オリジンかsrcdocから配信し、スクリプトを有効にするときはallow-same-originをオフにしておき、配信方法を管理できるならフレーム内のドキュメントにContent-Security-Policyも追加しましょう。
不透明なオリジンで何が変わるか
- allow-same-originがないと、フレーム内のドキュメントには同一オリジンポリシーに必ず失敗する特別なオリジンが割り当てられます。そのself.originは文字列 "null" になります。
- このルールひとつで多くの機能が止まります。フレーム内のページが、もはや自分のサイトの一部と見なされないからです。自分のCookieや保存した状態に依存するウィジェットはここで壊れることが多く、だからこそ多くのウィジェットがallow-same-originを求めます。
エラーなしで失敗するのが普通
- ブロックされたポップアップは例外を投げず、window.openが単にnullを返すだけです。ブロックされたアラートは何も表示せずにすぐ戻ります。ブロックされたフォームはただ何も起きません。埋め込みがおかしな動きをしたら、埋め込み側のコードを疑う前に、そのフレームのブラウザーコンソールを確認しましょう。
- このページのデモがフレームの中で結果を表示するのはそのためです。実際の埋め込みが直面するのと同じ、静かな挙動を確認できます。
sandbox、allow、CSPは役割が違う
- sandboxは、フレーム内のドキュメントができることを制限します。allow属性は、カメラ、フルスクリーン、位置情報などの機能に対する権限ポリシーを設定します。Content-Security-Policyはフレーム内ページのサーバーから送られ、そのページが読み込むスクリプトやリソースを制限します。
- 信頼できないコンテンツを慎重に埋め込むなら3つすべてを使います。そしてCSPのframe-ancestorsは逆の問い、つまり「そもそも誰がそのページをフレームに入れてよいか」を決めます。
すべてのsandboxトークン
トークンはスペース区切りで、大文字と小文字は区別されません。ここにないものはブロックされたままです。
sandboxトークンとそれぞれが許可する動作
- スクリプトの実行(ポップアップウィンドウは開けない)
- 不透明なオリジンではなく、ドキュメント本来のオリジンを保つ
- フォームの送信(許可しないと表示はされるが何も送信されない)
- alert()、confirm()、print()、prompt() の使用
- window.open() や target="_blank" でウィンドウを開く
- 開いた新しいウィンドウをsandboxなしで開かせる
- mailto: などのhttp以外のプロトコルを開く
- Storage Access APIによるパーティション分割されていないCookieの要求
コピーして使えるパターン
スクリプトを無効にしてユーザーのHTMLをプレビュー
フレーム内のボタンにはonclickハンドラーがありますが、空のsandboxでは実行されません。
別オリジンのサードパーティウィジェット
ウィジェットは自身のスクリプトを実行してフォームを送信でき、リンクは本物のタブで開けます。あなたのページをリダイレクトすることはできません。
同じ制限をレスポンスヘッダーで送る
サーバーはCSPで自身のページをsandbox化できます。この方法は、ページがフレームではなく直接開かれた場合にも適用されます。
トークンを切り替えてフレームをテスト
下のフレームはsrcdocのドキュメントです。ここではallow-same-originを選べません。srcdocフレームがこのページとオリジンを共有することになり、ヒントで注意している組み合わせそのものになるからです。
スクリプトがブロックされているため、このフレーム内では何も実行できません。
トークン
現在の属性
- スクリプトの実行(ポップアップウィンドウは開けない)
- 不透明なオリジンではなく、ドキュメント本来のオリジンを保つ
- フォームの送信(許可しないと表示はされるが何も送信されない)
- alert()、confirm()、print()、prompt() の使用
- window.open() や target="_blank" でウィンドウを開く
- 開いた新しいウィンドウをsandboxなしで開かせる
- リンクや遷移によるファイルのダウンロード
- トップレベルページの遷移
- トップレベルページの遷移(クリック後のみ)
- mailto: などのhttp以外のプロトコルを開く
- Pointer Lock APIの使用
- 画面の向きのロック
- プレゼンテーションセッションの開始
- Storage Access APIによるパーティション分割されていないCookieの要求
sandboxテスト用フレーム
スクリプトが実行されました。このフレームのオリジン:{v}
フォームを送信
ポップアップを開く
アラートを表示
フォームが送信されました。
フォームは送信されませんでした。
ポップアップが開きました(そして再び閉じました)。
ポップアップがブロックされました:window.openがnullを返しました。
アラートが表示されました。
アラートがブロックされました:表示されずにすぐ戻りました。
sandbox化したフレームからこんにちは
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る