アーキテクチャ・ジャーナル

ブラウザでのクロス・ドメイン通信のセキュリティ保護

Danny Thorpe
2009/04/20
Page1 Page2 Page3

送信者識別

 単純な iframe URL データ受け渡し手法におけるセキュリティ上の最大の問題は、データのソースが不明であることでしょう。送信者の名前または何らかの形のアプリケーション ID は、簡単にコピーできるので、それらを埋め込んでも問題の解決にはなりません。必要なのは、簡単にコピーできない方法により、メッセージで送信者を暗黙的に識別する方法です。

 ほとんどのユーザーを対象とした場合、最初に思い浮かぶのは、送信者と受信者のみが持っているキーを使用したなんらかの形の暗号化を使用することです。これは確実な方法ですが、特に JavaScript が関わってくる場合などは、かなり強引な方法です。

 もう 1 つの方法として、ブラウザ環境におけるドメイン名識別の重要性を利用した方法があります。私があなたのドメイン名を使用してあなたに機密メッセージを送信したとします。後でその機密情報をデータ パケットの一部として私が受信した場合、それはあなたのドメインから送信されたものであることを推定できます。

 サードパーティ ドメインからその機密情報が送信されたとすると、あなたのドメイン、ユーザーのブラウザ、または私の DNS にセキュリティ侵害があったことを意味します。あなたのドメインまたはブラウザにセキュリティ侵害があったとすると、すべて白紙に戻さなければなりません。DNS 汚染が現実的な問題である場合、https を使用すると、特定のドメイン名についてリクエストに応答しているサーバーが実際に正当なサーバーであることを確認できます。

 送信者が受信者に機密情報を提供し、受信者が送信者に機密情報を提供し、iframe URL データ チャネル上で送信されるすべてのデータパケットに両方の機密情報が含まれていれば、送信者と受信者はどちらも各メッセージのソースを信頼することができます。evil.com をソースとしている悪意のあるデータは、簡単に認識して破棄できます。この機密情報の交換は、SSL/https の 3 フェーズ ハンドシェイクから発想したものです。

 iframe URL データ チャネルを介して送信されるデータ パケットは、サードパーティからは見えないため、これらの機密情報は複雑である必要も暗号化されている必要もありません。機密情報としては乱数で十分ですが、警告事項が 1 つあります。JavaScript 乱数ジェネレータ(Math.random()) は、暗号学上強力ではないので、生成される数値のシーケンスが予測可能であるというリスクがあります。Firefox では、暗号学上強力な乱数ジェネレータ (crypto.random()) が提供されていますが、IE では提供されていません。その結果、実装では Web サーバー上で強力な乱数を生成してから、必要に応じてそれらをクライアントに送信することにしました。

送信者への送信

 iframe URL データ受け渡し手法に関連するほとんどの問題は、応答の生成に帰着します。パケットの受信確認には、受信者による送信者への返信が必要です。機密情報の交換では、双方向の返信が必要です。メッセージのスロットル、および大型のデータ ペイロードの複数の小さなメッセージへの分割には、受信確認が必要です。

 では、iframe はホスト ページとどのようにして通信できるでしょうか。それは、上位方向ではなく、下位方向の通信です。iframe とその親は異なるドメイン コンテキストに存在するため、iframe は親に属するものには何も割り当てることができません。しかし、bar.com iframe (A) には別の iframe (B) を格納することができ、A は B の src プロパティにホスト ページ (foo.com) のドメイン内の URL を割り当てることができます。foo.com ホスト ページには bar.com iframe (A) が、bar.com iframe (A) には foo.com iframe (B) が格納されます。

 なるほど。しかしその内部の iframe は何をするのですか。その親の bar.com iframe ではできることはあまりありませんが、もう 1 つ上のレベルでは、ペイダートに到達します。B の親の親は foo.com のホスト ページです。B のページは foo.com にあり、B.parent.parent も foo.com 内です。したがって、B はホスト ページ内のすべてにアクセス可能であり、ホスト ページのコンテキストで JavaScript 関数を呼び出すことができることになります。

 ホスト ぺージは URL を A の src プロパティに書き込むことにより、iframe A にデータを渡すことができます。A はデータを処理し、URL を B の src プロパティに書き込むことにより、ホストに受信確認を送信できます。B は onLoad イベントでスリープ状態を解除され、親の親であるホスト ページにメッセージを渡します。これで完成です。複雑な方法で接続された単一方向の一連のパイプからの往復受信確認です。数学者で何でも屋の Felix Klein も驚くことでしょう。

図 3: Klein Bottle のメッセージ

ステートフル レシーバ

 iframe に送信された複数のメッセージで bar.com コンテキストのグローバルな状態を維持するには、bar.com ページで 2 つの iframe を使用します。iframe の 1 つをステートレス メッセージ レシーバとして使用し、受信したメッセージごとにその状態を読み込んだり、なくしたりします。他方の iframe の bar.com 側には、ステートフル アプリケーション ロジックを配置します。メッセンジャー iframe ページ ロジックを、受信したデータをステートフルな bar.com iframe に渡すために必要な最小限に減らします。

 iframe は、その親の子を列挙して他の bar.com 兄弟を見つけることはできませんが、兄弟の iframe の名前がわかっている場合は、window.parent.frames[] を使用して兄弟 iframe を検索することはできます。URL で新しいデータを受信するために再読み込みをするたびに、メッセンジャー iframe は window.parent.frames[] を使用してステートフル bar.com 兄弟 iframe を検索し、ステートフル iframe で関数を呼び出し、新しいメッセージ データをステートフル iframe に渡すことができます。このようにして、ブラウザ メモリ内の bar.com ドメイン コンテキストは、複数のメッセージでのメッセージ チャンクを蓄積し、ブラウザの最大 URL 長よりも大きいデータ ペイロードを再構築することができます。

アイディアの応用

 Windows Live Developer Platform チームは、これらのアイディアをJavaScript " チャネル" ライブラリにまで進展させました。これらのクロス ドメイン チャネルは、サードパーティの Web ページに常駐し、live.com ドメイン コンテキストで、セキュリティ保護された iframe で実行されるように設計された Windows Live Contacts および Windows Live Spaces Web コントロール (http://dev.live.com) の実装に使用されています。コントロールにより、サードパーティ サイトでは、ユーザーの連絡先リストやスペース フォト アルバムなどの Windows Live データへのユーザー制御によるアクセスが可能です。チャネル オブジェクトは、iframe ドメインの境界を越えた任意の大型データの送信をサポートしており、受信確認、メッセージ スロットル、メッセージ チャンク、送信者識別など、すべてが暗黙のうちに行われます。

 弊社の目的は、このチャネル コード、内部のマイクロソフトのパートナーおよびサードパーティの Web 開発者が使用できる再利用可能なライブラリに仕立て上げることです。コードは現在のコンテキストで順調に機能していますが、自己診断およびトラブルシューティングの分野で改善の余地があります。チャネルのエンドポイントを正しく構成した場合は、優れた機能を発揮しますが、最初に設定しようとするときに、正しい構成となるように調整するのは大変な作業であることがあります。主な障害は、ブラウザ自体です。ブラウザでは別のドメインで何が行われているかがわからないので、異なるドメインで何が起こっているか、何が起こっていないかを判断することは課題です。

ユーザーのエンパワーメント

 米国の大通りで、店主は買い物客の支払いをそう簡単には受け入れませんでした。これはわずか 40 年ほど前のことです。現金 ( それも大金) を持っていなければ、あきらめるしかありませんでした。外貨を持っていた場合は、大都市の大銀行を見つけて現地通貨に交換しなければなりませんでした。地域外の小切手が受け付けられることはほとんどなく、ストア クレジットもその地域の住人しか利用できませんでした。

 今日、買い物客と店主は、グローバル通信システムおよびグローバル金融ネットワークを共有しています。これにより、買い物客はどこに行っても自分の銀行サービスを利用できます。また、店主は、現金なしでも販売できるので、商機を逃さずに済みます。さらに、金融ネットワークは、店主に対して、通貨の換算、クレジット リスクからの保護、詐欺による損害の削減などにより、インフラストラクチャ上のサポートを提供しています。

 では、インターネットでも、Web サーファーに対して同様な保護とエンパワーメントを、Web サイト管理者に対してインフラストラクチャ サービスを提供できないものでしょうか。買い物のときにクレジット カードによって自分の銀行サービスを伴うのと同様に、サイト間を移動する際にも自分のデータと経験を伴い、自分の判断によりサイト管理者に情報を開示するのです。インターネットがそこに到達するのは、その技量と時間の問題です。End of Article

謝辞

 独自の iframe URL データ受け渡し概念を開発した Scott Issacs に称賛を送ります。チャネル コードの初期の実装とデバッグに大きく貢献したYaron Goland および Bill Zissimopoulos、最近のイテレーションに携わった Gabriel Corverra および Koji Kato にも心から感謝いたします。
"狂気と言われるかもしれませんが、成功するかもしれません!"

参考資料

著者について

Danny Thorpe : Windows Live Developer Platform チームに属する開発者。役職は主任 SDE だが、扱いにくいこれらのビットを頑強な障壁を越えて移行させることに時間の大半を費やしているため、本人は "Windows Live クォンタム機械工" と呼ばれることを好んでいる。以前は Google で " 未公開のブラウザ技術" に携わっており、その前は、Borland の主任科学者、および Delphi コンパイラの主任設計士という経歴を持つ。Borland では、Anders Hejlsberg、Chuck Jazdzewski、Eli Boling、およびその他多数の Borland の伝説的な人物のもとで勤務するという幸運に恵まれた。Borland 以前のことは、若すぎたので覚えていないとのこと。筆者のブログは「Windows Live Quantum Mechanics」。


 

 INDEX
  [アーキテクチャ・ジャーナル]
  ブラウザでのクロス・ドメイン通信のセキュリティ保護
    1.複数のドメインへのデータ・アクセスするときの問題
    2.問題を回避するソリューション手法
  3.送受信の手法/アイディアの応用/ユーザーのエンパワーメント

インデックス・ページヘ  「アーキテクチャ・ジャーナル」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間