ifame(インラインフレーム)は、html中にフレームを埋め込めれるのですごく便利な機能である。しかし昔からセキュリティの面でいろいろ問題になってきた。
今回はIEがiframe内のクッキー処理をセキュリティでブロックした為、その対策方法を調べた。
現象のサンプル
ローカル環境でサンプルプログラムを作っています。ドメイン「localhost」のp3p_test.html からドメイン「192.168.24.61」の iframe_contents.html をiframeで表示しました。
同じサーバなのですがローカルIPで指定することでクロスドメインとして判定されて現象が再現できました。
【p3p_test.html】
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> <title>P3P_test</title> </head> <body> <iframe src="http://192.168.24.61/test/P3P/iframe_contents.html" width="200" height="100" ></iframe> </body> </html>
【iframe_contents.html】
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> <title>iframe_contents</title> <script type="text/javascript"><!-- window.onload = function() { //Cookie書き込み document.cookie = "p3p_test=test"; //Cookieの読み込み alert(document.cookie); } //--></script> </head> <body> in iframe </body> </html>
- p3p_test.html > 8行目 でドメイン192.168.24.61のiframe_contents.htmlをiframe表示しています。iframe元とiframe先のドメインが異なるのでクロスドメインとなります。同じドメインでは現象は発生しません。
- iframe_contents.html>10行目でjavascriptによりクッキーに書き込み処理をしています。
- iframe_contents.html>12行目でjavascriptによりクッキー情報を取得して、その内容をアラート表示しています。
IE7でページを表示させるとアラートがでますが、「p3p_test=test」の文字が表示されていません。クッキー処理が正常jに動いていないことがわかります。
同じページをfirefox3.6で表示させます。
firefoxではクッキー処理が正常に行われ、「p3p_test=test」の文字が表示されました。Google Chromeでも正常に処理がされます。
IEでクッキー処理がされない原因
IE7で原因を調査しました。
IEのフッターバーをみると「目玉に車両通行止標識」のアイコンがあります。
クリックしてみます。
プライバシーレポートのダイアログが開きました。プライバシー設定によりクッキーがブロックされたことがわかります。
インターネットオプション > プライバシーでIE7ではデフォルトで設定「中」になっています。この設定ではiframe内が別ドメインで、そのページがクッキーを使用しているとブロックします。
IE6以降では、P3P(The Platform for Privacy Preferences)というW3cで標準化されたプライバシー仕様を導入したようです。この為、自分で以外からきたクッキー情報をブロックするようになっています。
対策
(1)プライバシーの設定を「低」にする
インターネットオプション > プライバシーで設定を「低」にすることでブロックされなくなります。
「低」と「中」の違いは、
個人を特定できる情報を暗黙的な同意なしに保存するファーストパーティのCookieを制限します。
という制限の有無です。この制限によりデフォルトではクッキーがブロックされました。
(2)サイトごとのプライバシー操作で許可設定
インターネットオプション > プライバシー > サイトボタン をクリックすると「サイトごとのプライバシー操作」画面が表示されます。ここでWebサイトのアドレスを「許可」で登録するとブロックされなくなります。
(3)コンパクトポリシーをHTTPヘッダで出力する
(1)と(2)はユーザさんにブラウザ設定してもらう必要があります。自分がブロックされているサイトを見るのであれば特に問題はありませんが、サイト管理者の立場であれば、いちいち不特定多数のユーザさんに設定させるわけにはいきません。
原因がP3Pによるセキュリティが原因であることがわかっているので、プライバシーポリシーをサイト側で設定すれば解決します。
ただ、厳密なP3Pによるプライバシーポリシーを設定しなくても、このブロックを解除するだけならばコンバクトポリシーという、P3P ポリシー全体を要約したもので十分です。
コンパクトポリシーについて「マイクロソフト サポート オンライン>P3P プロジェクトについて」から引用します。
コンパクト ポリシーは、P3P ポリシー全体を要約したものです。コンパクト ポリシーはパフォーマンスを最適化するためのもので、これにより、ユーザー エージェントで、ポリシーの適用に関して迅速な、即座の決定が可能となります。P3P version 1 のコンパクト ポリシーに含まれているのは、cookie に関連するポリシー情報のみです。P3P コンパクト ポリシーの元となっている P3P ポリシー全体は、cookie 内に格納されているデータと cookie が参照している Web サイトにあるデータの両方に適用されます。コンパクト ポリシーは、P3P ポリシー全体で参照されているすべての cookie を表している必要があります。
P3P のコンパクト ポリシーは、ユーザー エージェントとサーバーのどちらに対しても任意のものであることに注意してください。ユーザー エージェントで、ユーザーのプライバシー基本設定を適用するために必要な情報をコンパクト ポリシーから入手できない場合、ポリシー全体を取得する必要があります。
コンパクトポリシーはHTTPヘッダーで出力します。
【p3p_test.html】
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> <title>P3P_test</title> </head> <body> <iframe src="http://192.168.24.61/test/P3P/iframe_contents.php" width="200" height="100" ></iframe> </body> </html>
【iframe_contents.php】
<?php header("P3P: CP='UNI CUR OUR'"); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> <title>iframe_contents</title> <script type="text/javascript"><!-- window.onload = function() { //Cookie書き込み document.cookie = "p3p_test=test"; //Cookieの読み込み alert(document.cookie); } //--></script> </head> <body> in iframe </body> </html>
- p3p_test.html > 8行目 でドメイン192.168.24.61のiframe_contents.phpをiframe表示しています。HTTPヘッダー出力をメタタグでしたかったのですが、正常に動作しませんでした。なので今回はphpでヘッダー出力します。iframe内のファイルをphpに変更しています。
- frame_contents.php>1~3行目で、コンパクトポリシーをヘッダー出力しています。「UNI CUR OUR」という文字列がコンパクトポリシーです。
コンパクトポリシーをヘッダー出力するとIE7でもクッキー情報が取得できました。コンパクトポリシーの文字列について説明するとかなり長くなるので、また機会あれば詳しく記事にしたいと思います。
対策としてはphpにより
<?php Header('P3P: CP="コンパクトポリシー"'); ?>
とクッキー処理の前にヘッダー出力します。サイトによっては
<meta http-equiv="P3P" content='CP="コンパクトポリシー"'>
でもいけるように書かれているところがありますが、色々試してもうまく正常しませんでした。メタタグでの対策については引き続き調べていきたいと思います。
「IEでクロスドメインのiframe内のcookieが取れない」への1件のフィードバック