blogこの広告は、90日以上更新していないブログに表示しています。2010-08-04iモードブラウザ2.0のJavaScriptではiframe内のコンテンツを読み出せないiモードブラウザ2.0では、同一ドメインであっても、iframe内のコンテンツがJavaScriptにより読み出せないよう制限が掛かっていることを確認しましたので報告します。【追記】元の内容には、重大な事実誤認がありました。正確には、同一ドメイン・同一ディレクトリであれば読み出せます。詳しくは追記2をご覧ください。徳丸浩の日記(2010-02-22)にて既に紹介したように、twitter.comの日本のケータイ向けフロントエンドであるtwtr.jpにDNSリバインディング脆弱性があったことを確認・報告し、直ちに修正されました。このエントリの中に、以下のように書いています。確認作業が終わるだろうと思っていたが、意外なところで失敗した。ログイン・リクエストのPOSTがうまくいかないのだ*1。早く確認を終わらせないと、もたもたしているうちに脆弱性を悪用されるとまずい。結局、XMLHttpRequestをあきらめ、IFRAME要素を用いることにした。最初、IRAME要素をDOMで動的に作ったりしていたのだが、IFRAME内のFORMをうまくSUBMITできない。このため、以下のような構成にした。徳丸浩の日記(2010-01-18)で報告したように、iモードブラウザ2.0ではsetRequestHeaderメソッドが殺されていたために、Content-Typeを設定できないことが原因でした。一つの、「IFRAME内のFORMをうまくSUBMITできない」件について、しばらく放置していましたが、この度検証しましたので報告します。その理由は、表題のように、iframe内のコンテンツに対してJavaScriptからのアクセスが禁止されたことでした。検証用スクリプト以下のコンテンツを用いて検証しました。ご覧のように、iframe内にdiv要素(id=innerdiv)があり、そのinnerHTMLを取得・表示するものです。pen.</div></body></html>Chromeでの実行結果(Firefox、Opera、Safariも同様)。932SHでの実行結果iモードブラウザ2.0(P-07A)での実行結果ご覧のように、iモードブラウザ2.0のみiframe内のコンテンツを読み出せず、iframeのcontentWindowおよびcontentDocumentはundefinedに設定されています。共用SSLサーバの危険性が理解されていないで紹介されている方法を少し改変して試してみました。id="out"></div></body>こちらの実行結果は以下のようになりました。inhibited」という例外が発生しています。iframe内要素を読み込めなくした理由は何かiモードブラウザ2.0でiframe内コンテンツを参照できないように制限が掛けられていることがわかりました。他のブラウザには、そのような制限はないので、なぜ制限を掛けたのか、その理由が気になります。ockeghem(徳丸浩)の日記で報告しているように、XMLHttpRequestで親ディレクトリのコンテンツを参照が禁止されたこととの関連です。以下のような仮説はどうでしょうか。一例として、二つのコンテンツが同一ドメイン上の別ディレクトリに配置されているとします。http://example.jp/~foo/http://example.jp/~bar/上記に示したような、同一ドメイン上の別ディレクトリに配置された別のコンテンツについて、相互にJavaScript等でアクセスができないように制限したという仮説です。「XMLHttpRequestで親ディレクトリのコンテンツを参照が禁止された」件は、まさにこれに該当します。共用SSLサーバの危険性が理解されていないで説明されているように、異なるディレクトリに配置されたコンテンツのCookie値を参照する方法として、iframeを使う手法があります。これを禁止したのではないかという仮説です。本当のところは分かりませんが、上記の仮説でつじつまが合うような気がします。PC向けブラウザではアクセスできるものが、iモードブラウザ2.0ではアクセスできことは、既存のJavaScript資産やプログラマの知識が有効活用できないことになり、かつNTTドコモの公式ドキュメントにもこのような記述は見あたらないことから、もっと情報をオープンしていただきたいものです。ソフトバンクに関して言えば、私が検証した932SHは、正式にJavaScriptが搭載された機種ではないことから、正式にJavaScriptが搭載された944SH/945SHではどうなるかが気になります。検証環境を公開しますので、944SHあるいは945SHをお持ちの方は試して頂けないでしょうか。QRコードから検証コンテンツを閲覧ください。18:00)id:harupuさんからブクマコメントを頂戴しました。普通にname属性使ってiframe_name.document.documentElement.outerHTMLとかで読めると思ったけど......。PC向けブラウザでもJavaScript自体まちまちな実装だし多少違いがあるのは仕方ないのでは。inhibited」という例外が発生します(2番目のスクリプトの結果参照)ので、意図的に禁止されているものと推測します。ソフトバンクとドコモは共にACCESS社のNetFrontブラウザを採用していることと、P-07Aより古い932SHがiframe内コンテンツにアクセスできて、新しいP-07Aはiframe内コンテンツにアクセスできないことからも、意図的な制限であることの傍証になると思います。20:15)id:harupuさんから再度のコメントをいただきました。ディレクトリ遡る話と混ぜてる?遡らなければN-06Aではできていりう。確認したところ、確かにそうでした。親コンテンツと同一ディレクトリもしくは、親コンテンツのサブディレクトリのコンテンツであれば、iframe_name.document.documentElement.outerHTMLなどで読み出せます(実際にはinnerHTMLで確認)。お詫びして訂正いたします。iframe自体はどのドメイン、ディレクトリであっても作れますが、JavaScriptを使ってiframe内のデータにアクセスするためには、同一ドメインかつ、同一ディレクトリまたはサブディレクトリのコンテンツに限るという条件がつきます。これは、XMLHttpRequestでデータを読み出せる条件と一致します。このため、実験の結論は間違ってしまいましたが、そうする理由の予測はかえって裏付けられたような気がします。ドコモは、何が何でも別ディレクトリのコンテンツをJavaScriptから読み出させたくないように思えます。