iframe sandbox:能力を絞るもので、強化するものではない
sandbox 属性は既定で全能力を奪い、allow-* で一つずつ戻します。方向を逆に覚えがちで、script が動かないのは既定値だからです。
<iframe sandbox> の意味は逆に覚えやすいです。空の値が最も厳格で、スクリプト・フォーム・同一生成元・ポップアップ・ダウンロードなどをすべて奪い、allow-* で個別に戻します。
<iframe sandbox="" src="/embed/comment.html"></iframe>
この iframe では JavaScript が動かず、フォームも送信できず、別の生成元として扱われます。静的な表示向きです。
能力を戻す
| 値 | 戻るもの | 危険度 |
|---|---|---|
allow-scripts |
JavaScript の実行 | 次の行と併用で危険 |
allow-same-origin |
元の生成元、cookie 参照 | scripts と併用で無意味化 |
allow-forms |
フォーム送信 | 中 |
allow-popups |
新しいウィンドウ | 中、フィッシング可能 |
allow-top-navigation |
最上位ページの遷移 | 高、ページを乗っ取れる |
最も危険な組み合わせ
sandbox="allow-scripts allow-same-origin" は、埋め込まれる側が親と同一生成元のとき実質的に無効です。スクリプトが動き、親の DOM にも触れます。つまり sandbox 属性を自分で消して再読み込みできます。
正しい方法は、埋め込む内容を別の生成元(独立したサブドメイン)に置くことです。そうすれば allow-same-origin は「サブドメイン自身の生成元」を意味し、オリジン間の分離は保たれます。
CSP の代わりにはならない
sandbox はこの iframe が何をできるかを、CSP はこの文書が何を読み込めるかを統制します。補完関係で、代替ではありません。
- インラインスクリプトを止める → CSP
script-src - iframe が親を遷移させるのを止める → sandbox
- iframe のリクエストを止める → iframe 自身の CSP のみ
実践的な設定
| 埋め込む対象 | 推奨 |
|---|---|
| 第三者コメント | allow-scripts allow-same-origin allow-popups |
| 動画プレイヤー | allow-scripts allow-same-origin allow-presentation |
| 静的な文書 | ``(空) |
| ユーザ投稿 HTML | iframe にしない。sanitize と別生成元 |
最後の行が下限です。ユーザ投稿の HTML を iframe で読み込んではいけません。 同一生成元の sandbox には回避の歴史があり、別生成元だけが信頼できます。
sandbox は許可リストで、拒否リストではありません。各
allow-*を書く前に、その能力が無いと何が起きるかを考えてください。

コメント
…