Hatena::ブログ(Diary)

最速転職研究会

2011-11-30

サードパーティCookieの歴史と現状 Part2 Webアプリケーションにおける利用とその問題

00:57 | サードパーティCookieの歴史と現状 Part2 Webアプリケーションにおける利用とその問題を含むブックマーク

前回 http://d.hatena.ne.jp/mala/20111125/1322210819 の続きです。

前回のあらすじ

といった事情を踏まえた上でWebアプリケーションにおけるサードパーティCookieの利用の歴史について書きます。前提知識の共有が済んだので、ここからはある程度個人的な意見も含まれます。実装面での技術的な内容も含みます。

サードパーティCookieが必要とされてきた歴史

広告のためのトラッキングCookie以外にも、サードパーティCookieに依存したサービスが数多く存在してきた。個人的に把握しているいくつかのサービスについて時系列で述べる。ついでに広告業界の流れについても重要なのを幾つか混ぜる。

2005年
  • MyBlogLogが開始
    • アクセス解析サービスで、ユーザ登録することでBlogに誰が訪問したのか分かるサービス。
    • 後に米Yahooに買収、日本でも類似のサービスがいくつか出ることになる。
2006年
2007年
  • 1月、YahooがMyBlogLogを買収する。
  • 4月、GoogleがDoubleClickの買収を進める
2008年
2009年
  • 1月、IE8RCがリリース、クリックジャッキング対策としてX-Frame-Optionsが導入される。
    • Webサイト側でフレーム拒否のヘッダを出力するというもので、サイト側の対応が必須であった。3月にIE8が正式リリース。
2010年
2011年

寸評

個々のサービスついて色々と思うところもあるが特にこの記事で深く掘り下げたりはしない、把握している範囲で述べているだけなので、これ以上に影響の大きいサービスもあったかもしれない。

Web開発者の多くは、単にブラウザの仕様に合わせてサイトを作っているだけで、自分の作るサイトがブラウザベンダーの意思決定に影響を与えているという自覚が希薄かも知れない。また「悪用されたら対策を考えれば良いだろう」とリリース時には単にspamやイタズラに使える程度であろうと考えていた脅威が、実際にはサービスの性質そのものに関わる問題であり対処のしようがない、と後から気付いた所で手遅れだったりもするだろう。ユーザーに対して「そのようなサービスを使うべきではない」と言った所で、自己責任で片付けられてしまうだろう。サードパーティCookieの送受信に依存したWebサイトを作る(あるいは使う)ということは、大多数のインターネットマニアでもセキュリティオタクでも何でもない普通の人たちがWebを安全に利用することができないという、そういう状況を肯定することに繋がっている。

Web開発者はどうすべきなのか?

  • まずWeb開発者は(少なくとも自分が開発に関わるサービスの動作確認をする時には) サードパーティCookieの送信をオフにすることを強く推奨する。ついでにリファラの送信も止めていい。
    • サードパーティCookieをブロックする設定にしたFirefoxGoogle Chromeで動作確認をすれば良い。
    • 上で挙げたような「ログイン状態のiframeやJSONを外部サイト上から利用する機能」が動かなくなる、ということを把握していれば、大した不便を感じることは無いだろう。
  • ブラウザは不適切なデフォルト設定を修正してこれなかっただけなので、自信を持っていい。IESafariを見習うべきである。
  • ユーザー目線に近いように「ブラウザデフォルト設定で使う」というポリシーの人もいるだろう。しかしこれは「本来ユーザーに与えられていた選択肢」を取り戻すためのものだ。
  • サードパーティCookieオフでは全く動作しない(ログイン出来ない、表示できない、無限リダイレクトする)ようなものは論外で、回避手段を用意すべきである。
  • 足あとを残すサービスは、そもそもが、悪意のある第三者に訪問者のユーザーアカウントを特定されるリスクが伴うことになることを理解すべきである。

ブラウザはこれからどうするべきなのか?

  • 2001年とは状況が変わっている、現実問題サードパーティCookieに依存したWebサイトが多くあり、トラッキングCookieを利用したターゲティング広告が広く普及し、その収益に依存したWebサイトが多く存在している。
  • (よほどユーザーの関心が高まらない限り) WebブラウザデフォルトサードパーティCookieをブロックするということが現実的にありえないという状況になっている。動作しないサイトが出てきて文句を言われるためだ。
    • デフォルトサードパーティCookieをオフにした場合、evercookieのような、ユーザーにとって、より一層制御が困難な追跡手段が広く用いられる可能性がある。
    • サイトごとにサードパーティCookieを許可するための設定が、より簡便に行えるようにならないと、多くのサイトが不具合を起こし、Web開発者の反発を招くだろう。
  • Do Not Trackの策定によってプライバシーを気にする人、トラッキングされたくない人はDNT: 1を送ればいいじゃん、という風潮になりつつある。
  • しかしDo Not Trackヘッダでは「ログイン状態で外部サイトに埋め込まれることによって発生している諸々のセキュリティ上の問題」が全く解決しないままである。

サードパーティCookieが無効でも動作するようにするにはどうすればよいか

ダメなシングルサインオンサービス編
ソーシャルボタン編

1. 単純に別windowでlikeなり+1なりスターなり押させれば良い

  • ログインの場合には、どうせ別windowで認証画面を開く実装になっているのが殆どである。
  • 別windowではファーストパーティCookieとして認証Cookieが送られるのだから、何の問題もない。
  • クリックジャッキングも防げる。
  • ユーザー毎に表示をカスタマイズしたりするのは、諦めるか、localStorageを使う

2. サードパーティCookie代替手段として、localStorageを使う

  • localStorageにユーザーを識別するためのAPI tokenなどを保存しておくことで、サードパーティCookieの代わりに使うことができる。
  • localStorageはCookieと違って、サーバーに勝手に送信されることがない。
  • 訪問した段階ではサーバーサイドで誰がアクセスしてきたのかを識別せず、ボタンをクリックした段階でユーザーを識別することが出来る。
  • 主サービスとCookieを共有しない別ドメインで提供すれば、ログインCookieトラッキング目的で使っているという疑いを晴らすことが出来る。

「全ユーザー共通のレスポンスを返す」ような埋め込みパーツは、この方式で完全に置き換えることができる。問題は「このページをいいねと言っている友人の一覧」など、ユーザー毎にパーソナライズされたレスポンスを出力する必要があるケースだ。幾つか解決手段があるだろう。

  • そのような機能を必要とする人に対して、Web履歴を把握されうることを周知させた上で、オプトインで提供する。
  • 友人の付けた「いいね」一覧をlocalStorageにキャッシュし、完全にクライアントサイドでパーソナライズされた表示を実現する。
  • アクセスログを共有しない第三者のサーバーを経由して、特定URL(またはURLハッシュ値)に対して特定ユーザーがいいねと言っているかどうか判別するAPIを提供する
  • iframe内のサードパーティlocalStorageに依存した認証を行なった場合に、確認なしで反映されるような機能はオプトインで提供されなければならない。
  • なぜかというとサードパーティCookieを無効化してもクリックジャッキングの被害に合うことになってしまうからである。
パーソナライズドホームページの類
  • OAuthを使う例が紹介されている http://code.google.com/intl/ja/apis/gadgets/docs/fundamentals.html#Cookies
  • 上記のように、今であればlocalStorageを代替手段として使うことも出来るだろう。
  • サーバーサイドでOAuthプロキシをしなくても、localStorageやpostMessageといったHTML5の機能を使うことで、クロスドメインでのデータの受け渡しは容易になっている。
    • 例えばiframe内からポップアップウィンドウを開き、Cookieで認証済みのポップアップウィンドウからiframeに対して認証が必要なデータにアクセスするためのAPI tokenをpostMessageで受け渡す、といった具合。
    • サードパーティlocalStorageが使える状態であるならば、tokenをlocalStorageに保存しておけば良い。
    • この方式であれば、tokenの受け渡しがブラウザ内だけで完結し、第三者のサーバーにtokenを受け渡す必要がない。

OAuthによる認可を与えたり、URLにpasswordやAPI tokenを付加するなどの方法が考えられるが、これは、ガジェット機能を提供しているプラットフォーム(この場合はGoogle)がその気になればユーザーのデータにアクセス可能であることを意味する。認証情報を預かっている以上、ユーザーに代わって操作できる状態になってしまうことが避けられない。つまり、プラットフォームが信頼できないのであれば、サードパーティCookieによって認証されたiframeを読み込んで直接操作したほうが安全、ということになる。外部サービスにidとpasswordを預けるよりもログイン状態のiframeを埋め込んだほうが遥かに安全である。

足あと機能や、勝手に共有の類
  • それは単純に自分のプロフィールを勝手に掲示板に投稿するというCSRF脆弱性そのものなので、作るべきではない。
クリックジャッキングのような問題にどう対処すれば良いのか
  • クリックジャッキングに対するブラウザベンダの対応はX-Frame-Optionsによってフレーム内表示を拒否するという方法だった。
  • 「iframeを使ってログイン状態で埋め込み、確認なしでワンクリックで反映される」という機能を作る以上、クリックジャッキングは防げない。
  • ログイン済みのiframeを外部サイトに埋め込むことを前提とした場合、そもそも安全に実装することが出来ない。
  • そのような機能を作るなといっても、もう作ってしまった場合にどうすれば良いのかについて述べる。
  • どうしても確認なしで実行することに拘りがあるのであれば「勝手にクリックされても、大きな影響がない程度の機能にのみ用いる」というアプローチが考えられる。

取り消しが可能な操作であっても、ボタンを押したことが第三者に伝わるのであれば、それは意図せずにユーザーアカウントを外部から特定可能な脆弱性となる

  • クリックした結果が知られるのが「自分のみ」に限定されているなら、意図せずにクリックされても影響は軽微と言えるだろう。単に効率の悪いspamである。
  • またクリック結果が知られるのが「友人のみ」でも、早期に気付くことが出来ればワーム的に拡散していくことは防げる。

クリックしたことをWebサイト側からスタイル制御不能なブラウザ側のUIで通知して、取り消し可能にするというアプローチもあるだろう

  • 単純にwindow.confirmでユーザーが実行しようとしたアクションに対して確認ダイアログを表示する。
  • ブラウザ拡張機能やWeb Notificationsと連携し、アクションを起こしたことの通知を出し、取り消し可能にする
    • 拡張機能を入れていない人に対しては確認画面を出せばよい

外部サイトに広く埋め込まれるようなサービスを設計する際にどうすればいいのか

  • 外部サイト埋め込みを前提としたサービスは、主サービスとCookieを共有しない別ドメインで提供し、登録ユーザーにだけ使わせるべきである。
  • ドメインにする理由は単純だ、Web履歴を収集されても構わないと考えているユーザーだけが有効化にすることが出来るからだ。
  • 「広告」や「外部埋め込みパーツ」にGoogleFacebookYahooなど、既にログインして広く受け入れられているCookieを用いることに、倫理的な問題がある。
  • ユーザーは単に提供される便利なサービスを利用するために、Cookieを受け入れたのであって、外部サイトのWeb訪問履歴を把握されうるということについて、正確な知識を持ち合わせていない。
  • (実際にやっているかどうかともかく) その気になれば彼らはGoogle Facebook Yahooのユーザーアカウントと紐付けて、外部サイトの訪問履歴を把握することができる。
  • 大手ポータルサイトSNSが、サードパーティCookieに依存した外部埋め込みパーツを提供し、サードパーティCookie無効では動作しない機能を提供してしまっている。
  • 単に実装した人が「サードパーティCookieオフで動作確認をしていないマヌケ」である可能性もあるが、意図的にこういったことをやっている可能性もある。
    • 穿った見方をすれば「外部サイトの訪問履歴を収集したいがために」意図的にサードパーティCookieに依存した機能を提供し「Cookieを全て受け入れる設定にしてください」という案内をしている可能性がある。

ブラウザの設定変更を促すことについての問題

まとめ

Part3ではターゲティング広告におけるトラッキングCookieの利用や、実装上の問題点について書きます。

トラックバック - http://d.hatena.ne.jp/mala/20111130/1322668652