<前の日記(2007年06月24日) 次の日記(2007年06月30日)> 最新 編集

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 51   昨日: 2746

2007年06月29日

EZwebサイトでSession Fixation被害発生か?

au booksでの事故

意図的な攻撃でなく偶発的な事故なのかもしれないが、auの公式サービス「au books」のEZwebサイトで、Webアプリケーションの脆弱性が原因の情報漏洩事故が起きたようだ。

  • 顧客情報漏えい:書籍販売サイト「au Books」で, 毎日新聞, 2007年6月26日

    ゲーム攻略本(1冊1890円)の紹介サイトからアクセスし、その攻略本を買おうとすると、他の顧客の氏名、住所、電話番号、生年月日、会員パスワードが表示された。そのまま購入手続きをとると、他の顧客が購入したことになってしまうという。

  • au携帯電話におけるオンライン書籍販売サイト「au Books」におけるお客様情報の誤表示について, KDDI, 2007年6月26日

    1. 発生事象

    本年6月22日20時37分から23日18時45分までの間、特定のリンク元サイトから「au Books」にアクセスしたお客様に対し、同じ時間帯にアクセスした他のお客様の登録情報 (氏名、住所、電話番号、生年月日、会員パスワード) が表示され、場合によっては、自分の情報が他のお客様の情報に書き換わってしまう事象が発生しました。 なお、誤って表示された可能性のあるお客様情報は最大436件、また書き換えられた可能性のあるお客様情報は最大124件です。

    2. 発生原因

    リンク元サイトから、「au Books」にアクセスしてきた同一のセッションIDを持つお客様に対し、「au Books」が、個別のセッションIDを付与できなかったために発生しました。

KDDIの発表に技術的な原因が書かれていて有益だ。この記述から推測するに、session fixationが起きていたのではないか。

対策が完了してサービス再開された後のau booksを訪れてみると、次の構成になっているようだ。

  • サイト内の任意のページに最初にアクセス時点でセッションIDが発行される。
  • 発行されたセッションIDは、cookieにセットされるとともに、URL rewritingにより、HTML中のサイト内リンクのリンク先URLに「;jsessionid=E34C50....」の形式で埋め込まれる。
  • ショッピングカートに商品を入れた後、注文画面に進むとき、登録済みユーザであれば、パスワードの入力を要求される(ユーザ名は要求されない)構成になっている。
  • パスワード認証後、送付先の住所等が表示される。
  • この間、「;jsessionid=E34C50....」はURLにずっと付けられており、値は変化しない。

その他、secure属性の付けられたcookieと、他に数個のcookieが発行されるようになっている。

改修前とどの部分が違っているか(対策により)は確認できないが、以下、事故当時に何が起きたのかを推測してみる。

まず、「特定のリンク元サイトからau Booksにアクセスしたお客様」に限ってこの現象が起きたということから、おそらくそのリンクは、次のように、セッションID入りのURLで記述されていたのだろう。

http://www.au-books.jp/item_detail.html;jsessionid=E34C50...?item_cd=MJ070.....

このリンクを辿ってアクセスするとき、現在の改修後のシステムでは、このセッションIDは破棄されるようだ。もし「JSESSIONID」というcookieに既に値が入っていれば、そちらの値が優先され、アクセスしたページに(URL rewritingで)埋め込まれる次のリンク先のURLには、そちらのセッションIDが埋め込まれる。また、「JSESSIONID」のcookieがまだ存在しない場合には、新たにセッションIDが発行されて、その値がSet-Cookieされ、次ページへのリンクのURL rewritingに用いられる。つまり、URL中の「;jsessionid=E34C50...」の部分は実質的に使用されていないに等しい構成になっているようだ。

これが、改修前では次のように動作していたのではないかと推測する。「JSESSIONID」のcookieがまだ存在しない場合、URLに指定された「;jsessionid=E34C50...」がセッションIDとして認識され、その値が「JSESSIONID」のcookieとしてセットされる――(A)。(あるいは、「JSESSIONID」のcookieが発行されていなかった可能性――(B)もある。)

こうした動作をすると、同じ時間帯にアクセスした複数の閲覧者が、同じ「E34C50...」のセッションIDでアクセスすることになる。ここで、Webアプリの構成が次のようになっていたとしよう。

  • ユーザがパスワードを入力してログインすると、そのときのユーザID*1がセッションオブジェクト内に記憶される。
  • ログイン中に個人情報をDBから引き出して表示する機能のページでは、このセッションオブジェクト内のユーザIDをキーにDBが検索される。

その場合、一人目のユーザ(1)がログインした後に、別のユーザ(2)がログインし、その後にユーザ(1)が個人情報を表示しようとすると、セッションオブジェクト内のユーザIDは(2)のユーザIDに書き換わっているため、ユーザ(1)の画面にユーザ(2)の個人情報が表示されるという事態が起きる(図1)。

説明図
図1: 同一のセッションオブジェクトを複数のユーザが共有してしまった状態
(黄色はセッションオブジェクト、緑は変数を表す)

通常「session fixation」という用語は、この脆弱性を持つWebアプリに対する意図的な攻撃を指して用いられる*2が、不慮の事故によって起きるこうした事態についても、「session fixation」という言葉を使ってよいのではないだろうか。

Session Adoptionに注意

特に、上記(A)のケースは、session fixationの中でも、その一形態である「session adoption」が起きていたと言える。「session adoption」とは、session fixation脆弱性に名前を付けた最初の論文「Session Fixation Vulnerability in Web-based Applications」で、攻撃手法の解説として、指定のセッションIDをブラウザに送り込む方法を列挙している中で定義された言葉であり、次のものを指す。

まず、WebアプリケーションがセッションIDをブラウザのどこに格納させる構成になっているかで分類すると、(a) URL引数への格納、(b) hiddenなINPUTフィールドへの格納、(c) cookieへの格納の3つ形態あるわけだが、(c) の場合に、攻撃者サイトから他のドメイン用のcookieをどうやってセットするのかが問題となる。攻撃対象サイトにクロスサイトスクリプティング脆弱性がある場合にそれを悪用するといった方法の解説がある中、他のケースとして挙げられているのが、「session adoption」である。

Session adoption

Some servers (e.g., JRun) accept any session ID in a URL and issue it back as a cookie to the browser. For example, requesting:
    http://online.worldbank.dom/?jsessionid=1234
sets the session cookie JSESSIONID to 1234 and creates a new session with that ID on the server6. We'll call such behavior "session adoption", due to the fact that the server effectively "adopts" a session ID that was generated by someone else.

6In JRun, it is required that a session with the proposed ID doesn't exist on the server yet in order for the server to return the session ID cookie. This may be different in other systems with similar behavior.

(訳)

セッション養子縁組

いくつかのサーバ(たとえばJRun)は、URLに書かれた任意のセッションIDを受け入れ、それをcookieとしてブラウザに発行し返す。たとえば、
    http://online.worldbank.dom/?jsessionid=1234
というリクエストを出すことは、セッションcookie「JSESSIONID」を「1234」にセットし、そのサーバにそのIDで新たなセッションを作成する6。サーバが実際上、他の何者かによって生成されたセッションIDを「adopt」する(養子にする)という事実から、我々はこのような挙動を「session adoption」(セッション養子縁組?)と呼ぶ。

6JRunにおいては、サーバがそのようなセッションID cookieを返すためには、提出されたIDによるセッションがそのサーバにまだ存在していないことが必要とされる。これは、同様の挙動をする他のシステムとは異なるようだ。

Session Fixation Vulnerability in Web-based Applications, 2002年12月

この脆弱性を持つWebアプリサーバとしてはPHPが最も有名であり、PHPセキュリティ界隈では「session.use_only_cookies をオンに設定する」ことが鉄則として叫ばれている。しかし、PHPだけでなく、上の文献にも書かれているように、J2EEのWebアプリサーバにも同様の挙動をするものがあるらしい*3

au booksのサイトでどのWebアプリサーバが使われていたのかは知らないが、他のサイトでも注意が必要だろう。

ログイン前Session Fixationの対策は?

一般に、session fixationの対策は、次のいずれかを達成すればよい。

  • セッションをfixされないようにする。
  • セッションをfixされても問題がないように、必要なタイミングでセッションIDを振り直す。

セッションをfixされないようにするには、まず1つにsession adoptionが起きないようにすることである。セッションIDの格納場所として前記の(a)や(b)を採用せず、(c)を採用した上で、session adoptionが起きないWebアプリサーバを使う*4。しかし、残念ながらそれだけでは解決しないのが現状である。2006年10月21日の日記に書いたように、ブラウザに「Cookie Monsterバグ」があるとそれができてしまうのであり、ほとんどのブラウザで未解決だからだ。ただし、サイトを構築したドメイン名によっては影響を受けない場合もある。au booksの場合は、「au-books.jp」であるから、第2レベルで確定するので「Cookie Monster」の影響を受けないであろう。また、携帯電話のブラウザの「Cookie Monsterバグ」がどうなっているかは興味深いところだが、まだ調べていない。

セッションをfixされても問題がないようにする場合、最も単純なのは、ログイン後までセッションIDを発行しない(セッションを作成しない)ようにすることであるが、au booksのように、ログイン前からショッピングカートのためにセッションを作成する必要がある場合には、それを採用できない。

そのような場合においては、ログイン直後にセッションIDを振り直すという方法が知られている。しかし、はたしてそれで解決なのだろうか。2006年10月29日の日記「ログイン前Session Fixationをどうするか」に書いていたように、ログイン前の状態をセッションハイジャックされた場合、何かの被害が出ると言えるかが焦点となる。

ショッピングサイトの場合、買い物をしようとしている被害者が、悪意あるサイトからのリンクを辿ってサイトに到着した場合、買うつもりのない商品までカートに入れられていることに気づかずに決済画面に進んでしまうということが起こり得るが、攻撃が成功する確率は低めであるし、はたしてそのような攻撃を誰がしたいと思うか? という疑問がある。

だが、今回の事故では、誰も意図していないのに、数百人もの人が同じセッションを共有してしまう事態が起きたわけだ。これは、リンク元が信頼のおけるサイトだったことがひとつの要因であろう。「攻撃」ではなくても、事故でセッションのfixationが起きれば、誤発注が多発してサービスを中止せざるを得ない事態が生じ得る。

その意味で、少なくとも、意図せずセッションをfixするようなリンクができてしまう事態はいかなる場合も避けた方がよいということは言えそうだ。幸い、session adoptionを避ける方法はあるのだから、Webアプリサーバをそのように設定すればよい。

残る問題は、「Cookie Monsterバグ」を突いてたとえば「.co.jp」全域で有効な「JSESSIONID」を発行するようなサイトが存在する場合であるが、意図的な攻撃でなく、誤設定でそのようなことをしているサイトである場合には、そのセッションIDは固定であるから、(最初を除いて)必ず無効なセッションIDとなっているはず*5なので、存在しないセッションの「JSESSIONID」cookieを無視する(受け入れてしまわない)ようにしておけばよい*6

そうすると最後に残るのは、意図的に特定サイト用の新鮮なセッションIDをコピーしてCookie Monsterでセットしてくる攻撃(まさにsession fixationの典型)であるが、ログイン前でそれをされることがどのくらい困る事態なのかによって、対策しなくてよい場合もあるかもしれない。

サブスクライバーIDをパスワード代わりに使うべきでない理由

このようなsession fixation対策が面倒だという場合、携帯電話特有の対策方法として、サブスクライバーIDを用いる方法が考えられる。

上記の図1でも、ログイン時にサブスクライバーIDを参照してセッションオブジェクトにuseridとして格納したわけだが、それをせずに、view操作の際に直接サブスクライバーIDを参照するようにすれば前述の問題は起きない。これは、サブスクライバーIDがアクセス毎に毎回送られてきているから実現できることだ。

別の方法として、ログイン時にセッションオブジェクトにサブスクライバーIDを記憶し、その後の各ページのアクセス時に、リクエストに含まれるサブスクライバーIDとそれが一致しているかを確認する方法もあり得る*7。それはちょうど、2007年2月23日の日記「携帯電話向けWebアプリの脆弱性事情はどうなっているのか」で参照した、WEB+DB PRESS誌Vol.37に掲載の記事「携帯サイト開発 実践テクニック 2007」にも書かれていたことである。

携帯サイトでセッションを使うときの注意点

携帯ブラウザの場合,Cookieを使うことができませんので,セッションを使う際はどうしてもURLにセッションIDが含まれてしまいます.URLにセッションIDが含まれる場合はセキュリティに注意する必要があります

本人以外がセッション付きのURLにアクセスできないようにしましょう.特に検索サービスにクロールされてしまうと問題は深刻です.個人情報が簡単に検索できてしまいます.

そのため,セッションには必ず端末IDを保存しておいて,特定の端末のみアクセスできるようにしておきましょう.(略)セッションに格納されている端末IDと照合することで,違う端末からのアクセスをチェックすることができます

携帯サイト開発 実践テクニック 2007, 技術評論社 WEB+DB PRESS Vol.37, p.127

改めて振り返ってみると、携帯用Webサイトではこれまでにもたびたび「誤表示」の事故が起きていた。例えば次などの報道があった。

こうした事故は、いわゆる「race condition脆弱性」(メモリ上のオブジェクトが短時間にセッション間で共有されるプログラムミスや、同じ名前の一時ファイルを使用してしまう欠陥などが原因で、高負荷時に発現するもの)によっても起きることが知られてきたが、今回のau booksと同様に、session fixationによって起きていたものもあったのかもしれない。

「携帯向けWebアプリは危ない」という話は以前からいろいろな人から耳にするが、具体的なことが表立って語られることがほとんどなく、安全な実装が普及しないという問題があった。

上のWEB+DB PRESS誌の記事の著者は、session fixationによる誤表示の問題が実際に起きていることを知っているがゆえに、「URLにセッションIDが含まれる場合はセキュリティに注意する必要があります」と書いたのかもしれない。

その対策方法として、サブスクライバーIDを用いることが書かれていたわけだが、私はその方法をお勧めしない。auの場合にはcookieがサポートされているのだから、cookieを使って、PC向けサイトと同様に対策をすればよい。(au booksはおそらくそのように対策されていると思われる。)

サブスクライバーIDを使わないべきなのは、次の理由による。

サブスクライバーIDは、ユーザに固定の固有IDであり、どのサイトにも同じ値が送信されるものであるため、国民総背番号制に対して示される懸念と同様のプライバシー上の問題がある。そのうえ、ワンクリック不当請求などに悪用される差し迫った現実の危険性も存在するため、できるだけ早く廃止すべき仕組みである。もし、携帯Webアプリの脆弱性に対してサブスクライバーIDを頼りに対策するサイトが増えると、廃止すべき仕組みを廃止しようにも廃止できなくなってしまうのが問題だからだ。

そしてもうひとつ理由がある。

WEB+DB PRESS誌の記事では、次のようにも書かれていた。

端末認証

登録が必要なサイトの場合,利用する際にはログインが必要です.ID/パスワードを毎回入力するのでは,携帯の場合では特に面倒です.

そこで携帯ならではの認証方法として,現在の端末では取得が容易にできる端末自体の情報(端末ID)を利用します.

携帯サイト開発 実践テクニック 2007, 技術評論社 WEB+DB PRESS Vol.37, p.126

これに対し私は2007年2月23日の日記「携帯電話向けWebアプリの脆弱性事情はどうなっているのか」で次のように書いた。

そもそも、「ID/パスワードを毎回入力するのでは携帯の場合では特に面倒です」などといって、端末IDをパスワード代わりにしてはいけない。端末IDは他のサイトにも同じものが送信されるのだから、パスワード代わりになどならない。

これはひとつには、同日記の脚注1にも書いていたように、この記事には、キャリアのIPアドレスからのアクセスであることの確認の話は書かれていなかったことも問題であるわけだが、もうひとつ、次の理由がある。

SSLの利用を必要としているサイトを想定してみる。携帯電話でもSSLは利用されている。携帯電話のWebにおいてどこに盗聴のリスクがあるかというと、キャリアのゲートウェイからWebサーバまでの通信路が主であろう。そこに本当に盗聴のリスクがあるのか? という疑問を抱く人がいるかもしれないが、携帯電話でSSLが必要とされているサイトがあるのは事実である。

その場合に、サブスクライバーIDをパスワード代わりに用いるのは明白に脆弱性と言える。なぜなら、図2のように、通信路上の盗聴者はパケットを改竄するなり、あるいは独自のIPパケットを送出することにより、キャリアのIPアドレスからの任意のサブスクライバーIDを送信することができてしまうからだ*8

説明図
図2: 通信路上の攻撃者がキャリアのIPアドレスからの任意のサブスクライバーIDを送信する様子

これができてしまうのは、サブスクライバーIDが攻撃者に既知となるためである。

こうした事態を避けるには、ランダムに生成されるセッションIDをcookie(secure属性を指定した)に入れてSSLで通信すればよい。PCのWebでは普通そのように実装されている。

問題は、cookie機能がサポートされていない、NTTドコモなどの携帯電話であろう。iモードでは、cookie機能がないため、URLにセッションIDを入れることが広く行われているようだ。それは、前述の(B)および(a)のタイプの構造であり、session fixationに弱い。

NTTドコモは早くcookieをサポートするべきだ。携帯Webの危うさは、NTTドコモがcookieをサポートしないことが主要因ではないのか。EZwebと同様に、ゲートウェイにcookie機能を作りこめば、全端末に対応できるのではないのか。

*1 このサイトではユーザ名が存在しないので、EZwebのサブスクライバーID (最近では「EZ番号」と呼ばれるようになった)がユーザIDとして用いられていると思われる。

*2 図1で言えば、User(1)が攻撃者でUser(2)が被害者とすると、(User(1)のloginは省くことができ、)User(2)がログインしたころを見計らって、User(1)がviewの操作をするとUser(2)の個人情報を意図的に盗むことができてしまう。

*3 上記文献の脚注6には、JRunでは存在しないセッションのセッションIDが指定されたときだけこの挙動をするとされているが、他の製品ではそうではない(いつでも受け入れてしまう)ことが示唆されている。

*4 EZwebでは、cookieをサポートしているので、この対策を採用できる。

*5 偶然に有効なセッションIDに一致してしまう確率はゼロではないが、当てずっぽうのセッションIDでセッションハイジャックできる確率と同じはず(セッションIDが暗号学的に安全な擬似乱数生成器で生成されていれば)なので、無視できる。

*6 domain属性の異なる同名の「JSESSIONID」cookieがリクエストに送られてくることになるので、全部をサーチして有効なものだけ使うようにするか、あるいは、セッションを開始する際に、domain属性が「.co.jp」などのcookieを消すSet-Cookieをするようにしておく対策が考えられる。

*7 これにより、セッションハイジャック全般を防止できるわけだが、それは、そもそもセッションIDすらいらないことを意味する。サブスクライバーIDをセッションID代わりに使えばよい。つまり、セッションオブジェクトをサブスクライバーIDで参照するように、Webアプリサーバを作ればそれが可能である。

*8 これができないというのなら、SSLもいらない。

本日のTrackBacks(全3件) [TrackBack URL: http://takagi-hiromitsu.jp/diary/tb.rb/20070629]

なんだろうけど、携帯電話のいわゆる端末固有情報 (ICC等) が専らよろしくないのは、ユーザがどのページにアクセスしても同じIDが送信されるということがある。いきなり廃止という議論をするのではなく、とりあえずURLとIDの値のハッシュをとってそれを端末が送るように..

EZwebサイトでSession Fixation被害発生か?より。 この記...

検索

<前の日記(2007年06月24日) 次の日記(2007年06月30日)> 最新 編集

最近のタイトル

2024年11月11日

2024年07月28日

2024年07月27日

2024年07月07日

2024年04月07日

2024年04月01日

2024年03月23日

2024年03月19日

2024年03月16日

2024年03月13日

2024年03月11日

2023年03月27日

2022年12月30日

2022年12月25日

2022年06月09日

2022年04月01日

2022年01月19日

2021年12月26日

2021年10月06日

2021年08月23日

2021年07月12日

2020年09月14日

2020年08月01日

2019年10月05日

2019年08月03日

2019年07月08日

2019年06月25日

2019年06月09日

2019年05月19日

2019年05月12日

2019年03月19日

2019年03月16日

2019年03月09日

2019年03月07日

2019年02月19日

2019年02月11日

2018年12月26日

2018年10月31日

2018年06月17日

2018年06月10日

2018年05月19日

2018年05月04日

2018年03月07日

2017年12月29日

2017年10月29日

2017年10月22日

2017年07月22日

2017年06月04日

2017年05月13日

2017年05月05日

2017年04月08日

2017年03月10日

2017年03月05日

2017年02月18日

2017年01月08日

2017年01月04日

2016年12月30日

2016年12月04日

2016年11月29日

2016年11月23日

2016年11月05日

2016年10月25日

2016年10月10日

2016年08月23日

2016年07月23日

2016年07月16日

2016年07月02日

2016年06月12日

2016年06月03日

2016年04月23日

2016年04月06日

2016年03月27日

2016年03月14日

2016年03月06日

2016年02月24日

2016年02月20日

2016年02月11日

2016年02月05日

2016年01月31日

2015年12月12日

2015年12月06日

2015年11月23日

2015年11月21日

2015年11月07日

2015年10月20日

2015年07月02日

2015年06月14日

2015年03月15日

2015年03月10日

2015年03月08日

2015年01月05日

2014年12月27日

2014年11月12日

2014年09月07日

2014年07月18日

2014年04月23日

2014年04月22日

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|06|07|08|10|11|12|
2017|01|02|03|04|05|06|07|10|12|
2018|03|05|06|10|12|
2019|02|03|05|06|07|08|10|
2020|08|09|
2021|07|08|10|12|
2022|01|04|06|12|
2023|03|
2024|03|04|07|11|
<前の日記(2007年06月24日) 次の日記(2007年06月30日)> 最新 編集