AMPにおける「Origin of <amp-iframe> must not be equal to container 」エラーとIframe origin policy 、さらには<iframe>の`sandbox`について

公開:2017-09-02 20:50
更新:2017-11-15 21:58
カテゴリ:AMP,静的ブログジェネレータ,HTML,IFRAME,iframe origin policy

AMPページにおけるエラー

このブログのAMPページの<amp-iframe>で、下記のエラーが出て困っていた。

Origin of <amp-iframe> must not be equal to container 
<amp-iframe>のオリジンはコンテナと同じであってはいけません。

sandbox属性にはallow-same-origin属性は入れているのだが。なぜだろうか。エラーの続きには以下のメッセージが続いていた。なぜかメッセージ的には分割して表示されてしまっているのだが。

if allow-same-origin is set.See https://github.com/ampproject/amphtml/blob/master/spec/amp-iframe-origin-policy.md for details.

合わせるとこういうことか。

Origin of <amp-iframe> must not be equal to container if allow-same-origin is set.See https://github.com/ampproject/amphtml/blob/master/spec/amp-iframe-origin-policy.md for details.

もしallow-same-originをセットしているのなら、<amp-iframe>のオリジンはコンテナと同じであってはいけません。詳細はhttps://github.com/ampproject/amphtml/blob/master/spec/amp-iframe-origin-policy.md を参照すること。

「同じオリジンのiframe srcを許して」いるのに同じオリジンであってはいけないとはどういうことか。しかしそもそもオリジンって何だ?

Origin(オリジン)とは

オリジンは以下で定義される。

なので、同一のオリジンとは

となる。つまり

は同一オリジンだけど、

はすべて異なるオリジンということになる。

異なるオリジンのページへのスクリプトアクセス

異なるオリジンのページ同士はスクリプトアクセスが制限される。具体的にはwindow・Locationのメソッド・プロパティに制約を受ける。

引用:MDN

Window

使用できるメソッド
window.blur
window.close
window.focus
window.postMessage
使える属性 読み取り・書き込み
window.closed 読み取りのみ
window.frames 読み取りのみ
window.length 読み取りのみ
window.location 読み取り/書き込み
window.opener 読み取りのみ
window.parent 読み取りのみ
window.self 読み取りのみ
window.top 読み取りのみ
window.window 読み取りのみ

Location

使えるメソッド
location.replace
属性 読み取り・書き込み
location.href 書き込みのみ

上記以外のwindow,locationのメソッド・属性は使用できないということか。

<iframe>sandbox属性allow-same-origin

sandbox属性 - iframe 要素 - HTML | MDN」を読むと、私はsandbox属性に関して何もわかっていないことが分かった。

一番の誤解は、allow-same-originトークンが同一オリジンのiframeを許すのではなくて、別オリジンのiframe srcを同じオリジンだとみなすという部分。 考えてみると同一オリジンのiframe srcが読み込めないはずないもんね。。

あとMDNには以下のことが書いてあった。

Iframe origin policy

allow-same-originを誤解していたことがわかり、sandboxが理解できたところで、エラーメッセージのURLのドキュメントを見ると、わりと理解できたような気がしたが、今いち自信がないね。。。

AMPはAMPプロキシでキャッシュされるので、必ずオリジンのホストからページが供給されるとは限らない。なのでもし<amp-iframe>内のページのJSがホストしているページが同じオリジンであることを前提に作られていると、AMPプロキシでキャッシュされた場合不具合が起こる可能性がある。例えば(クロスiframeアクセス)を使用しているものを考える。AMPページはキャッシュされ、別オリジンで提供され、<amp-iframe>内のページはキャッシュされない(ユーザーJSが動いている時点でAMPの要件を満たさないからかな・・)可能性がある。その場合別オリジンとなってホストページ<->iframeアクセスに制限がかかり不具合が発生する可能性がある。

AMPは上記不具合を回避するため、「sandbox属性でallow-same-originを指定した場合は<amp-iframe>srcは別オリジンでなければならない」ルールを定めている。<amp-iframe>のコードは別オリジンを前提とすることを強制させるのである。同一オリジンの場合「Origin of <amp-iframe> must not be equal to container」エラーが発生する。 さらにホストページに対してはpostMessageのみ利用可能な制限がかかる。 このルールはsandobox属性でallow-same-originを指定しない場合は適用されない。が別オリジンの場合のiframe制約がかかる。

そうするとあれだな、

ということをすればよいのだろうかね。。