<前の日記(2009年08月01日) 次の日記(2009年08月15日)> 最新 編集

高木浩光@自宅の日記

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

2009年08月02日

やはり退化していた日本のWeb開発者「ニコニコ動画×iPhone OS」の場合

一年前、「退化してゆく日本のWeb開発者」という題で、ケータイWebの技術面での蛸壺化について次のように書いた。

iPhoneに契約者固有ID送信機能が搭載される日

(略)こうして退化してゆくケータイWebが、日本のスタンダードとなってしまい、いつの日か、PC向けの普通のインターネットまで、単一IDの全サイト送信が必須になってしまうのではないかと危惧した。

(略)iPod touchでNAVITIMEを動かしてみたところ、下の図のようになった。 (略)契約者固有IDがないとどうやって会員登録システムを作ったらいいのかわからないんじゃないのか……というのはさすがに穿ち過ぎだと思いたい。NAVITIMEからソフトバンクモバイルに対して、契約者固有ID送信用プロキシサーバの用意を要請している……なんてことがなければいいのだが……。

無責任なキャリア様に群がるIDクレクレ乞食 ―― 退化してゆく日本のWeb開発者, 2008年7月27日の日記

また、10月の越後湯沢での講演で次のスライドを示した。

スライド

そして、今年の4月末のこと。「iPhoneにまで進出してくる」との危惧が、現実になっていた。

ニコニコ動画のiPhone OS用アプリが登場したというので、さっそく入手し、アカウント設定の画面に進もうとしたところ、次の画面が現れた。

iPod touchの画面 iPod touchの画面
図1: ニコニコ動画のiPhone OSアプリ曰く「端末情報を取得します。よろしいですか?」

「端末情報を取得します。よろしいですか?」という。iPod touchなのに?

そこで、ニコニコ動画のサポート窓口に次の質問をした。

画面キャプチャ
図2: ニコニコ動画への問い合わせ

すると、すぐに回答があり、

「iPhone版ニコニコ動画」は端末情報(端末製造番号)によってログイン時(毎回)に会員状態を識別しております。そのため、登録時や動画視聴時は端末情報を送信した上でお手続を進めてください。

とのことだった。そこで、続けて、「私は iPod touch 使用しています。iPod touch は携帯電話ではありませんが、「端末製造番号」なるものが、iPod touch にもあるのでしょうか?」と質問したところ、迅速に回答があり、

はい、iPod touchにも端末製造番号が存在しており、ログインアカウントに紐付ける形でユーザーを識別しております。

とのことだった。この間に自力で調べた(自分の無線LAN経由での通信内容を傍受して調べた)ところ、送信しているのは、iPhone OSに搭載されている「UDID」という文字列だとわかった。そこで、「これを送信することは、貴社のプライバシーポリシーに違反しているのではないでしょうか?」と尋ねたところ、すぐに回答があり、

端末製造番号については、その端末を識別する為の番号ですので、仮にお客様がその端末を第三者に譲渡した場合なども、端末製造番号を以って持主を特定することはできないものと存じております。

従いまして、現状のご利用方法が弊社のプライバシーポリシーに反したものであるという認識はございません。

という。ならばなぜ「端末情報を取得します。よろしいですか?」とわざわざ確認するのだろうか。問題があると認識しているからこそ確認を出しているはずなのに、問題はないのだという。携帯電話がそういう流儀になっているので、なんとなく真似て出しているだけなのだろうか。

まあ、その件はいい。それよりも、携帯電話でもないのに「UDID」を使っているということは、セキュリティ上の脆弱性があると推定される。なぜなら、無線LAN経由でも使うのだから、携帯電話のように「IPアドレス帯域」でアクセス元を限定して対処することは不可能だからだ。

自分の通信内容を無線LAN電波を傍受して調べたところ、図3のように、一部でHTTPSが使われていたが、その他はHTTPで通信していた。ニコニコ動画のiPhone OSアプリは、図1の図のように、ニコニコ動画のユーザIDとパスワードを登録して使うようになっているので、このパスワード送信の際にHTTPSが使われているのだろう。

画面キャプチャ
図3: ニコニコ動画iPhone OSアプリの通信挙動

最初のHTTPの通信内容は図4のようになっていた。

画面キャプチャ
図4: 最初のHTTP通信「/v1/login」

「udid=」と「ticket=」という2つのパラメタが渡されている。ticketの値は、ニコニコ動画の会員番号とランダムっぽい値の連結になっており、後者は、おそらく、HTTPSでパスワードを送信して認証成功した際に返されてきた、認証が成功したことを伝える一時的な値であろう。それと共に「UDID」が送信されている。

このHTTPリクエストで、サーバ側でこの「UDID」がニコニコ動画のアカウントと結びつけられるものと考えられる。このときのHTTPレスポンスには、メールアドレスやニックネーム、ニコニコ動画の会員番号等が含まれていて、これらはプライバシー情報にあたるが、このレスポンスはticketがないと得られないものになっているだろう。

しかし、「マイリスト」機能にアクセスしたときは、図5の通信内容となった。

画面キャプチャ
図5: 「マイリスト」機能使用時の通信内容

このHTTPリクエストでは、「UDID」だけを送っている。つまり、UDIDだけでログイン状態を維持していることが推定される。HTTPレスポンスには、私の非公開設定の「マイリスト」の内容が含まれている。

これはまずい。では、「UDID」というのは、どのくらい他人に知られ得る値なのだろうか。

日本のケータイWebの場合、契約者固有IDはすべてのWebサイトに送信されるので、誰でも知り得る値であるが、iPhone OSの場合はそうではない。Safariがそのような値を送信するようになっているはずもない。

「UDID」がどのようなものか調べてみたところ、iPhone OSアプリ開発者らの間で広く使われているものだった。「UDID」は通常は目にすることがないが、iTunesの図6の画面で、シリアルナンバーの部分をクリックすると「UDID」が表示されるようになっている。

画面キャプチャ
画面キャプチャ
図6: iTunesでの「UDID」の表示

これがどんな目的で使用されているかというと、ひとつには、開発中のアプリのベータテスト用で、AppleのApp Storeに登録される前の開発中のアプリを、ベータテスト目的で誰かに試用させる際に、試用者に「UDID」を提出させて、特定の「UDID」の機器だけで動作するように限定してベータ版を提供するということが行われているようだ。

つまり、「UDID」は他人に知られる場合があることを想定したものである。したがって、「UDID」の送信だけで「マイリスト」を閲覧できてしまうのは、他人にも閲覧できるということであり、「マイリスト」には非公開設定もあるので、これは、ニコニコ動画の脆弱性(Webサイト側のセッション管理上の脆弱性)である。

ただし、上の図4のように、アプリを起動する毎にパスワードによる認証があるので、一定期間だけ「UDID」だけでアクセス可能にするという制御が行われている可能性はある。そこで、翌日まで放置(ニコニコ動画アプリを使わないで)した後に、telnetで直接(自分の)「UDID」を指定してアクセスしてみたところ、「マイリスト」を取得できることが確認できた(図7)。

画面キャプチャ
図7: 自分で自分になりすまして直接アクセスした様子

以上のようにして、実際的な問題のある脆弱性であることがわかったので、「ニコニコ動画お客様サポート」に対し、以下のように脆弱性の報告をした。*1

株式会社ニワンゴ 情報セキュリティ対応係 御中

ニコニコ動画のiPhone OS向けサービスのセキュリティ脆弱性について

iPhone OS向けの「ニコニコ動画」アプリを利用しておりましたところ、その実装手段に技術的な誤りがあり、他人に非公開マイリストを閲覧されてしまうなどの被害の生じ得る、セキュリティ脆弱性があることに気付きましたので、以下の通りお知らせします。

1. ニコニコ動画アプリの挙動

iPhone OS向けの「ニコニコ動画」アプリを、無線LAN経由のインターネット接続で使用し、その際の通信内容を自分で傍受して調べたところ、iPhone OSの「UDID」が送信されていることに気付きました。

「ニコニコ動画」アプリの「アカウント設定」でメールアドレスとパスワードを設定した状態で、たとえば、「マイリスト」のひとつを閲覧しようとすると、i.nicovideo.jp:80 に対し、以下のHTTPリクエストが送信されるようです。

GET /v1/mylistgroup.get?udid=88d0e4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&detail=1 HTTP/1.1
User-Agent: iPod touch
Accept: */*
Accept-Language: ja-jp
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: i.nicovideo.jp

ここで、「udid=」の右の40字の文字列は、私のiPod touchのUDIDです。このHTTPリクエストは、任意のIPアドレスから送信しても受け入れられるようで、携帯電話会社のゲートウェイ等にアクセス元を限定しているわけではないようです。そのため、iPhoneまたはiPod touchを用いずに、通常のパソコン等から上記のHTTPリクエストを送信した場合にも、レスポンスは通常通りに得られ、XML形式で記述された私のマイリストの内容が返信されてくることを確認しました。

2. セキュリティ上の問題点

上記の挙動から、HTTPリクエスト上のいずれのパラメータにも秘密情報が含まれておらず、UDIDだけでユーザ固有の情報にアクセスできることがわかります。このことから、誰かのiPhoneまたはiPod touchのUDIDを知ることができれば、誰でもその人に成り済ましてアクセスできるはずであると推察されます。

iPhone OSにおいてUDIDは秘密情報ではありません。UDIDは、たとえば、iPhone OS用アプリの開発者が、ベータテストのためにテスターを募集する際に、テスターに提出を求める情報として使われており、開発者は他人のUDIDを知る立場にあります。また、他のWebサイトがUDIDを使うようになると、あちこちのWebサイトが人々のUDIDを保有することになります。UDIDは、ユーザIDの代替になることはあっても、パスワードの代替になるものではありません。

Apple Inc. の、Developer Connection の文書「iPhone Reference Library」にも、UDIDについて次のように記載されており、ユーザ認証の目的で使用できないものであることが暗に示唆されています。

http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIDevice_Class/Reference/UIDevice.html

uniqueIdentifier
Discussion
A unique device identifier is a hash value composed from various hardware identifiers such as the device’s serial number. It is guaranteed to be unique for every device but cannot publically be tied to a user account. You can use it, for example, to store high scores for a game in a central server or to control access to registered products. The unique device identifier is sometimes referred to by its abbreviation UDID.

3. 生じ得る被害

私が調べた範囲では、非公開のマイリストが他人に閲覧される点を確認しました。他にも、他人に成り済ましてコメントを書き込まれる可能性、非会員に動画を閲覧される可能性、プレミアム会員に成り済まして利用される危険性などが考えられますが、確認はしていません。

4. 正しい実装方法

現在の「ニコニコ動画」アプリは、「アカウント設定」でメールアドレスとパスワードを設定して使うように設計されており、アプリを起動した際にメールアドレスとパスワードを送信して、アカウントの有効性確認の認証処理を行うよう作られているようですから、本来、UDIDを使う必然性は全くないはずです。

正しい実装方法は、ログイン毎に異なるセッションIDを用いることです。メールアドレスとパスワードでログイン認証した時点で、サーバ側でセッションID(暗号用乱数を用いた十分な長さの予測困難な文字列)を生成して「ニコニコ動画」アプリに渡し、アプリ側はそれをメモリ上に記憶して、アクセス毎にHTTPリクエストに載せて送信するようにすれば、サーバ側で、そのセッションIDを用いたセッション管理を実装できるはずです。

アプリとサーバ間のセッションIDの受け渡しには、HTTPレスポンスのSet-Cookie:ヘッダと、HTTPリクエストのCookie:ヘッダを用いることもできるでしょうから、そうすることで、PHPの既存のセッション管理機構をそのまま使うこともできるのではないかと思います。

5. プライバシーの保護

UDIDはプライバシーに関わる情報であるとも言えます。もし、多くのWebサイトがUDIDを用いるようになれば、UDIDによって、誰が利用しているのかが他のWebサイト運営者にわかってしまう事態が生じます。

ニコニコ動画のiPhone OS向けサービスが上記の通り正しい実装に修正され、ニコニコ動画の運営上UDIDが不必要なものとなれば、これまでに収集されたUDID情報は廃棄されることが望ましいと思います。

以上

そして、7月13日に「ニコニコ動画 for iPhone Ver 1.05」がリリースされ、7月31日をもって旧バージョンの使用が停止となり、この脆弱性は解消された。図8のように、旧バージョンでは動作しないことが告知されている。*2

iPod touchの画面 iPod touchの画面 iPod touchの画面
図8: ニコニコ動画からの告知

修正された現在では、「UDID」は送信されなくなり、図4のところでセッションIDが発行されるようになり(図9の「<session_id>」)、図5のところではそのセッションIDが送信されるようになった(図10の「sid=」)。

画面キャプチャ
図9: 「/v2/login」でセッションIDが発行された様子

画面キャプチャ
図10: セッションIDによって「マイリスト」が閲覧された様子

また、図7と同じことをしても図11のようにエラーとなり(何やらエラーメッセージが見えているが)、脆弱性は解消された。

画面キャプチャ
図11: エラーとなるようになり脆弱性が解消された様子

というわけで、この事例のように、日本のケータイWeb開発者が、普通のWebアプリケーションの構築技法からかけ離れて、蛸壺化していることがうかがえる。

類似の話として、徳丸浩氏の7月14日の日記では、ケータイWeb開発は入門書籍からして蛸壺化しつつあり、その弊害としてCSRF対策もままならなくなっていることが指摘されている。

日本の携帯電話事業者の一部は、「フルブラウザ」にさえ契約者固有ID送信機能を持たせて、蛸壺の維持を謀ろうとしているが、iPhoneのような国際的デファクト標準には通用しないのであって、今後も、他のスマートフォンの普及とともに、蛸壺的手法は通用しなくなっていくであろう。

そのときに、蛸壺の中の開発者らが、このニコニコ動画の事例と同様のミスをする可能性が高い。「IPアドレス帯域」による制限が通用しない機器では、アプリケーションの内容によっては特に危険な脆弱性となるので、関係者はこのことに注意が必要である。

なお、1年前に軽く触れたNAVITIMEのiPhone OS用アプリの件はどういうものだったかというと、NAVITIMEでは「会員登録」時に、図12のように、「http://www.navitime.jp/smartphone/EntryFacade_uid_XXXXXX……」というURLで、何やら固有IDを送信するようになっていた。おそらく、「UDID」を暗号化した(あるいは一方向性関数に通した)もの*3だったのだろう。

iPod touchの画面 iPod touchの画面 iPod touchの画面
図12: かつて存在したiPhone OS用NAVITIMEの会員登録画面の挙動

NAVITIMEでは、ニコニコ動画と違って、ユーザ名とパスワードの登録機能を持っていなかった。そのため、最初に「会員登録」をするときに、固有IDをSafari経由で送信して、そこで決済用のクレジットカード番号の入力をさせることで、この固有IDに直接クレジットカード番号を紐付ける構成になっていたと思われる。そして、NAVITIMEアプリが有料サービスを実行するときは、この固有IDだけで認証状態を維持していたものと推察する。

このような構造の場合、脆弱性を指摘されてもすぐには直せない。なぜなら、新たにユーザ名とパスワードの機能を用意して、既存のユーザに再登録を促さない限りどうともならないからだ。

NAVITIMEは元々、日本のケータイWebが発祥なので、ケータイ同様に作ればユーザIDとパスワードがなくても認証できると勘違いしてしまったのだろう。蛸壺方式をそのままiPhoneに適用しようとして破綻したのではないか。*4

このことからも、ケータイWebで蛸壺化することのリスクが大きいとわかる。はじめから普通のインターネットでも使うことを想定してサービスを設計しないと、こういう事態になる。

2007年の「モバイルビジネス研究会」が、「ユーザーIDの利活用の推進」としてユーザIDの統一化を謀っていたこと(「日本のインターネットが終了する日」参照)は、このような意味でも日本を駄目にする方向性だったと言える。幸い、2008年の「通信プラットフォーム研究会」では、関係者のご尽力により、この種の問題を指摘する声があがり、SAMLやOpenID(おそらくはOAuthも)を使用することが検討される方向性になった(「通信プラットフォーム研究会 傍聴録」参照)。

ニコニコ動画の事例が解決できたように、「ケータイの契約者固有IDがないと便利なサービスを実現できない」などということはないのであって、特に、Webブラウザではなく個別のアプリでサービスするときには、ニコニコ動画のようにユーザIDとパスワードを設定しておく構造にすればよいわけであるし、初回利用時にユーザIDとパスワードを作成することがケータイユーザにとって煩わしいのが問題であるのなら、SAMLないしOpenIDを活用すればよい*5と考えられるし、Webブラウザの場合であっても同様のはずだ。

*1 IPAの脆弱性届出窓口にも、Webアプリケーションの脆弱性として届け出た。これは、ニコニコ動画iPhone OS用アプリの修正が必要な脆弱性であるが、Webサイト側が対策すれば脆弱性は解消するのであるから、ソフトウエア製品の脆弱性ではなく、Webアプリケーションの脆弱性である。

*2 旧バージョンをそのまま使い続けても(動作しないだけであって)脆弱性の被害を受けるわけではないので、脆弱性が存在したことの告知はなされていない。

*3 この場合、暗号あるいは一方向性関数の内容がバレてしまうと、危険な脆弱性となる。そして、暗号アルゴリズムと暗号鍵、あるいは一方向性関数のアルゴリズムは、配布されていたアプリのコードの中に書かれているのだから、解析されればバレてしまう。

*4 私は、気づいたときにはもう、NAVITIMEのiPhone用サービスが終了しかけていたので、事実を突き止めるところまで検証できなかったが、既に誰かが脆弱性を指摘していたか、内部で判明していたのかもしれない。

*5 ただし、ケータイユーザが使いこなせるのか、使いこなせるようなUIはどうあるべきかという点の検討が必要と思われる。

本日のTrackBacks(全100件) [TrackBack URL: http://takagi-hiromitsu.jp/diary/tb.rb/20090802]
The Very Times 日本版:Story added (2009年08月04日 03:13)

Your story was featured in The Very Times 日本版! Here is the link to vote it up and promote it: http://jp.verytimes.com/node/390

検索

<前の日記(2009年08月01日) 次の日記(2009年08月15日)> 最新 編集

最近のタイトル

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|
<前の日記(2009年08月01日) 次の日記(2009年08月15日)> 最新 編集