GMailのコンタクトリスト漏洩とプライベートJSONP
GMailのコンタクトリストが外部から呼び出し可能になってしまってた件について。
Google内プライベートなはずのデータが、関係のない外部のサイトからもスクリプト経由で読み込まれてしまうというもの。
http://ajaxian.com/archives/gmail-csrf-security-flaw
でもこれってCSRFっていうのかな?なんか問題がちょっと違ってるような気もするけど。CSRFは情報が抜き取れるかどうかってとこは別に関係ないはずだし。外部サイトにプライベートデータを盗まれるという脅威としてはCSSXSSに近いような。(追記:どうもCSRFの定義ってのはもうちょっと広いみたい)
この騒ぎに呼応して、クロスサイトのセキュリティモデルについてまとめてあった。
http://labs.cybozu.co.jp/blog/kazuho/archives/2007/01/crosssite_security.php
一方、Google の GMAIL コンタクトリスト漏洩は、ウェブアプリケーション開発者側の問題です。CSS や JavaScript のコードはクロスサイトで参照可能なので、その中に秘密情報を含めてはいけないのです。JSON については、JavaScript として副作用をもたない (もたせようがない) ゆえに
文法違反であるがゆえに、秘密情報を含むデータフォーマットとして使用することができるのです
JSONはJavaScriptとして副作用はないけど、JSONPはそのままJavaScriptとして通用する。結局今回のGMailの件も、コンタクトリストデータのJSONサービスが、URLにcallback引数をうけとってJSONPとして呼び出せたところが拙かった。
つまり、コンタクトリストのようなプライベートかつ秘密にするべき情報はJSONP化してはだめ。Ajaxしたいなら素直にXMLHttpRequestでピュアJSONを使いなさい。
...という結論がたぶん正しいんだろうけどなあ。
でも、ここはあえてJSONPでプライベート情報を配信させたらどうなるだろうと考えてみることにしました。
結局この件の問題は、あるサイトに保管されているプライベート情報を外部サイトがユーザにまったく同意なく取得する(=盗む)ことが可能になってしまっているところにあると思う。
もしユーザがその外部サイトを信頼し、データを預けてもよいと判断したのだったら、その2つのサービスの間でデータが流れていくことは別に問題ないだろう。むしろコンタクトリストのようなデータはいろんなサービスで使えるため、可搬性があったらいいと思っているユーザは多いかもしれない。
たとえば何らかのフォーマットでファイルとしてエクスポートしてからそのサービスにデータをインポートするのでもよいといえばよいけど、そういった作業はいちいち面倒で、カジュアルにサービスを使う妨げになるかもしれない。また、次のサービスに完全移行するのでない限り、複数のアクティブなデータストアを持つことになってしまい、データの同期についても気にする必要が出てくる。
JSONPであれば、クロスドメインの制約を越えているので、そういったサービス間でプライベートデータを持ち回りたいという要求に応えることができる。もちろん先のGMailのようにまったく好き勝手に読み込まれては困るけれども、呼び出し元(この場合はJSONP呼び出しを行う外部のサイト)が何らかの形で認証された上でアクセス許可のロジックが埋め込まれればよい。
ということで、詳細は以前書いたエントリへ。
念のため、この話は今のところかなり思考実験に近いので、実際にちゃんとセキュリティホールなどなく使えるのかどうかもっと検証してみる必要があると思っている。あえてJavaScriptでやる必要はないでしょという意見もあるだろうし、そのための各種Webサービス認証だろうという話もある。また、そもそもこういったユースケースは本当にあり得るのかという根本的な疑問も実はある。
ただ、このGMailの件で、かなりJSONPの使い方について風当たりが強くなりそうな予感がして、ちょっと残念。まあ正しいといえば正しいんだけどなあ。