要約
X-Frame-Options: SAMEORIGINは、別サイトによる埋め込みを断るためにページが送る応答ヘッダーだった。2013年のRFCは、保護対象と最上位のページだけを比べるブラウザー実装の死角を記録した。- AのページがBを埋め込み、BがAの保護ページを埋め込む。両端だけを比べればAとAが一致し、間のBを見落とす。2016年のW3C仕様は全ての祖先を調べる
frame-ancestorsを定めた。
同じ色の二枚に挟まれた一枚
サイトAのページにサイトBのフレームがあり、BがさらにAの大切なページを囲む。内側のAはX-Frame-Options: SAMEORIGINを返す。ブラウザーに、同じオリジンのページからだけ埋め込ませる指示だ。ところがブラウザーが内側と一番外側だけを比べれば、どちらもAになる。Bのページはすぐ隣にいるのに調べられず、内側のAが表示される。
2013年10月のRFC 7034はこの経路を説明した。当時のヘッダー運用と実装差を記録したInformational文書である。背景にはクリックジャッキングがある。画面を重ね、利用者が見ているボタンとは別のページのボタンを押させる攻撃だ。RFCに出てくる通販の購入確認は防御を説明する例であり、A/B/Aは仕組みを示す構図である。特定の店で起きた事件の記録ではない。
サーバーの命令とブラウザーの視線
保護されるページはHTTP応答でX-Frame-Optionsを送る。DENYは全てのフレームを拒み、SAMEORIGINは同一オリジンを許し、ALLOW-FROMは一つの許可先を指定した。ページの持ち主が境界を決め、ブラウザーが守るという分担だった。
ただし、入れ子が増えると検査する相手が変わる。RFCはブラウザーごとの扱いの差を記した。最上位と保護対象だけを比べる実装では、間に挟まる別オリジンのページを見ない。ヘッダーは存在する。失敗するのは文言ではなく、親をたどる処理の深さだ。両端が同じサイトでも、その間のページまで同じとは限らない。
祖先を一人ずつ調べる
W3Cが2016年12月に勧告したCSP Level 2はframe-ancestorsを定めた。保護対象をフレームへ読み込む前に、ブラウザーは全ての祖先を並べ、各ページのURLを許可先と照合する。一つでも一致しなければ読み込みを中止する。A/B/Aなら真ん中のBで止まる。外側のAが許可されていても結果は変わらない。
W3Cは、古いSAMEORIGINの多くの実装が最上位だけを調べていた点を明示し、新しい指令が全祖先を調べると説明した。frame-ancestorsはX-Frame-Optionsを置き換え、両方が届いた場合はCSP側を適用すべきだとも記した。許可先を複数書けるようになったことも改善点だが、中心は検査の単位を窓二つから経路全体へ変えたことにある。
命令を置く場所にも条件があった。RFCによれば、X-Frame-Optionsをmeta http-equivへ書いてもブラウザーは無視した。W3Cもframe-ancestorsをmeta要素で配信する方法を認めない。CSPにdefault-src 'none'だけを書いても埋め込み禁止にはならない。ページはブラウザーが処理する応答に、埋め込みの規則を明記する必要がある。
ページの持ち主は自分を囲める相手を指定できる。利用者のブラウザーだけが実際の入れ子全体を見られる。書かれた境界の強さは、そのブラウザーが何代前まで確かめるかで決まった。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
ストラテジックサークル限定
ストラテジックサークル
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
ストラテジックサークルに参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加





