中間者攻撃のもとでのCookie InjectionによるHTTPSの盗聴・ハイジャックについて、次のようなアナウンスが出ている。
- Vulnerability Note VU#804060 - Cookies set via HTTP requests may be used to bypass HTTPS and reveal private information
- JVNVU#92999848: HTTP リクエスト経由で設定された Cookie によって HTTPS 接続がバイパスされたり情報漏えいが発生する問題
ここでは、アナウンスで参照されている論文の内容を簡単にまとめてみる。
Cookie Injectionとは
HTTPは本来ステートレスなプロトコルだが、これにステートを持たせる仕組みとしてCookieがあり、広く用いられている。
Cookieでは、サーバがSet-Cookieレスポンスヘッダでname-value形式の値を送り(あるいはJavaScriptのdocument.cookie
から値を書き込み)、クライアントがこれを記憶する。
その後、クライアントがCookieリクエストヘッダで記憶している値を送ることで、トランザクションに固有の状態(ログイン済みか否かなど)を持たせることができる。
Cookieは古くから存在する仕様なため、そのアクセスコントロールポリシーはDOM操作やXMLHTTPRequestで適用されるSame-origin policyとは異なる。
具体的には、domain/path属性やsecure属性によりCookieが送信される条件が指定される。
Same-origin policyではサブドメイン(foo.example.com)とその上位ドメイン(example.com)は別々のスコープとして扱われるが、Cookieのポリシーではサブドメインはその上位ドメインのスコープの一部として解釈される。
そのため、foo.example.comからdomain=.example.com
のCookieをセットすることができるとともに、bar.example.comではdomain=.example.com
のCookieが適用される。
この仕組みのもとでは、次の2種類の攻撃が成立する。
- Cookie Overwriting
- foo.example.comとbar.example.comの両方で
domain=.example.com
のCookieを利用している場合、foo.example.comからbar.example.comで使われるCookieを上書きすることができる。また、Cookieにsecure属性を指定することでHTTPSの場合のみCookieを送信するようにできるが、このCookieは同一スコープのHTTPからでもセットが可能である。したがって、HTTPの中間者攻撃によりsecure属性付きのCookieをセットすることで、後続するHTTPS通信で攻撃を成立させることが可能である。
- foo.example.comとbar.example.comの両方で
- Cookie Shadowing
- www.example.comで
domain=www.example.com; path=/; secure
のようなCookieを利用している場合、evil.example.comからdomain=.example.com; path=/home
で同一のnameを持つ値を登録することで後者を優先させることができる。これは、Cookieの仕様(RFC 6265)でpathの詳細度を優先順位に用いるように推奨されており、Safariを除く主要ブラウザの実装がこれに従っているためである。また、secure属性の有無は優先順位に影響しない。
- www.example.comで
この問題はRFCにも記載があり、2004年の時点ですでに報告も上げられているが、問題の詳細や具体的な攻撃可能事例については十分な調査がされていなかった。 論文では、中間者攻撃のもとで起こりうる具体的な攻撃可能事例を挙げ、それらによりもたらされるリスクについて報告が行われている。
また、プロクシがHTTP CONNECTメソッドでのHTTPSリレー要求に対しSet-Cookieヘッダ付きの407レスポンス(proxy authentication required)を返したとき、IE以外の主要ブラウザはこのCookieを記憶する。 悪意あるプロクシがこれを利用すると、HTTP Strict Transport Security(HSTS)が完全に有効なHTTPSドメインに対しても攻撃が可能となることが報告されている。
攻撃可能事例
論文では、Cookieの利用ケースを3種類に分類し、合わせて10個の攻撃可能事例が報告されている。 なお、これらの脆弱性はすべて報告済みとのこと。
Cookies as Authentication Tokens
CookieをSession IDの記憶に利用しているケース。
Case-1: Gmail chat gadget hijacking
google.comはHTTPでアクセス可能であるため、ここからGmail chatのpathに一致するようにSession CookieをShadowingすることで攻撃者のchat gadgetに差し替えることができる。
Case-2: “Invisible” Google search history stealing
Case-1と同様にして、domain=www.google.com; path=/
でCookie Overwritingすることでターゲットの検索履歴を攻撃者のアカウントで収集することができる。
ただし、ログインユーザのユーザ名とアイコンが攻撃者のものとなるため、偽装しておく必要がある。
Case-3: Credit card stealing on China UnionPay
カード情報を追加する際の送信先URLに対しSession CookieをShadowingすることで、攻撃者が難読化されたカード番号と支払履歴を得ることができる。
Case-4: Deposit hijacking on JD.com
Eコマースサイトでのデポジット(入金)操作の第2ステップにおけるSession CookieをShadowingすることで、攻撃者がデポジットを得ることができる。
Case-5: Account hijacking against Google OAuth and BitBucket
Safari特有のCookie実装を利用してOAuth認証URLにCookie Injectionを行うことで、攻撃者のOAuthアカウントにターゲットのBitBucketアカウントを結び付けることができる(association violation)。
Cookies as References to Session Independent States
CookieをTracking IDの記憶に利用しているケース。
Case-6: Shopping cart tracking/manipulation on popular E-commerce websites
Tracking Cookieを攻撃者が用意したものにOverwriteすることで、攻撃者がショッピングカートの中身を取得したり操作することが可能になる。
Case-7: Browsing history and purchase tracking/hijacking on Amazon
Amazonにおいて、Tracking Cookieを攻撃者が用意したものにOverwriteすることで、攻撃者がリアルタイムで閲覧履歴を収集することが可能になる。 また、そこから購入が進められた際、配送先や支払方法も含めた情報を収集することができる。
Cookies reflected into HTML
Cookieが設定値の記憶に利用されており、それがHTMLにそのまま出力されているケース。
Case-8: XSS via cookie injection on China Construction Bank, Amazon Cloud Drive, eBay and others
書き換えられたCookieが検証されず、そのままHTMLに出力されることによるXSSが存在する。
Case-9: Insufficient cookie validation on Bank of America
複数のCookieを使うことで、一度だけ行われるCookieの検証をバイパスしてXSSできる。
Case-10: BREACH attacks on phpMyAdmin and MediaWiki
そのままHTMLに出力されるCookieの値を利用し、ネットワーク監視によりレスポンスサイズの変化を観測することでCSRF tokenの特定ができる(BREACH attack)。
既存技術によるリスク低減
論文では、既存技術による三つのリスク低減手法が提示されている。
Full HSTS and Public Suffix List
サブドメインを含めたすべてのドメインでHTTP Strict Transport Security(HSTS)を利用して、初回の接続時以降は常にHTTPSが使われるようにする。 また、複数のウェブサイトでドメインを共用している場合のペストプラクティスとして、ドメインを分けた上でそれらをPublic Suffix Listに登録し、注意深く運用することが挙げられている。
Defensive Cookie Practices
Full HSTSが難しい場合は、DefensiveなCookieの運用を行う。 たとえば、Session Cookieを破棄する頻度を高くする。 クロスドメイン、クロスプロトコルでの状態の共有が不便になるが、Cookieの代わりにlocalStorageやsessionStorageのようなHTML5の機能を使うこともひとつの方法となる。
Anomaly Detection
Cookieヘッダで同一のnameを持つ値が複数送られていることを検知する。 これにより、Safari以外のブラウザ利用者をCookie Shadowingから守ることができる。
クライアントサイドでの防御手法の提案
論文では、既存のCookie実装を拡張する形での防御手法の提案も行われている。 具体的な内容を示すと次のようになる。
- HTTPにおいてsecure属性の付いたCookieを受け入れない
- secure属性の付いたCookieを優先する
- 各nameについて、最も優先度が高い値のみを送信する
- 保存容量を越えた場合は、secure属性のないCookieから消す
- HTTPにおいて、「do not send」属性の付与によるsecure属性付きCookieのクリアを許す。この際、元の有効期限の情報は残しておく
- 「do not send」属性の付いたCookieおよび同一nameを持つCookieの送信を行わない
- secure属性のあるCookie、domain属性の詳細度の高いCookieの順で優先する
5と6は、1の例外としてHTTPで提供されているログアウトページでsecure属性付きのSession Cookieを消すケースを考慮したものである。 また、7は詳細度の高いpath属性でCookie Shadowingが可能であることに対する対策である。
所感
別のサブドメインからのCookie Injectionも可能であることから、単純に一つのサブドメインについてHSTSを有効にするだけでは効果が薄い。
広く見られるhttp://www.example.com/
とhttps://secure.example.com/
の分離では不十分ということが実例をもって示されており、情報の重要度を問わずすべてをHTTPS化するという流れとブラウザ実装の改良の両方を促すことになるものと思われる。