2016年8月3日水曜日

安全!? #PokemonGo のログインと OpenID Connect と PokeIV

こんにちは、富士榮です。

今回はもPokemon Goとアイデンティティのネタです。


前回、前々回とPokemon Goのログインの流れを見てきました。

 攻略! #PokemonGo のログインと OpenID Connect
 http://idmlab.eidentity.jp/2016/07/pokemongo-openid-connect.html

 続!#PokemonGo のログインと OpenID Connect
 http://idmlab.eidentity.jp/2016/07/pokemongo-openid-connect_25.html


これまでのポストでは、主にGoogleでログインすることで、Googleサービスへの不要なアクセスができる状態になっていないか?という観点で調査をしてきましたので、Scopeパラメータを見る限りはメールアドレスくらいにしかアクセスしていないことが分かったので、ひとまず安心、という結論を出していました。


◆Pokemon Goのふりをするアプリの登場

しかし、逆にPokemon Go側から見ると、Pokemon GoのサービスへのアクセスはGoogleから取得したid_tokenを持っていることだけを条件にしているので、何とかしてPokemon Goアプリの”ふり”をしてid_tokenを取得してしまえば、あとは何とでもなる、という状態でもありました。

最初のポストを書く時に、OpenID ConnectでGoogleからid_tokenを取得する流れを見ていると、public clientにもかかわらずimplicitではなくcode flowを使っており、codeやclient_secretが丸見えな点にものすごく違和感を感じて、サードパーティ・クライアントでも作るつもりなのかな???など、色々と議論をしていたんですが、やはり出てきてしまいました。

 PokeIV : 個体値チェックサイト
  https://pokeiv.net/



Gigazineでも紹介されていますが、Pokemon Goで使っているアカウントでGoogleにログオンし、codeを取得しPokeIVに貼り付けることでPokemon Goへアクセスして個体情報を取得するという仕組みなのですが、内部的には、Pokemon Goのclient_idとclient_secretを使ってPokemon Goのサービスへアクセスできるid_tokenを取得しているようです。

以下の同意画面を見るとクライアントがPokemon Goになっており、クエリパラメータの中のclient_idを見るとiOS版のPokemon Goで使っているclient_idと同じものが使われています。


Googleに登録されているredirect_uriがurn:ietf:wg:oauth:2.0:oobなので、redirect_uriにクエリでcodeを渡す代わりに、取得したcodeを手動(コピペ)で渡し、tokenエンドポイントを叩く、という実装はしていますが、色々とタチが悪いですね。

最近OpenID Foundation Japanの事務局長になったnov氏がoauth.jpで書いているようにcode置き換えもあるでしょうし、そもそもclient_secretが漏れている段階で今回のPokeIVのように単純にPokemon Goのふりをしてデータを取得するようなクライアントの開発が出来てしまいます。

今は集めたポケモンの情報をとってくるだけ、ということになっているので良いんでしょうが、例えば、今後Pokemon Goからユーザの位置情報の履歴を取得できたりすると、一気にホラーな話になってしまいますよね。。。


◆Pokemon Goはどうすれば良かったのか?

そもそも論、HTTPSを使っているにも関わらずFiddlerでトレースできてしまう段階でCertificate Pinningなどの対策が出来ていない、という話もありますが、ネイティブアプリ(パブリック・クライアント)として実装している段階で逆コンパイルや解析をされる前提でOpenID ConnectやOAuthの設計をすべきです。具体的にはimplicit flowを使ったり、Google Sign-In SDK for iOSを使って、client_secretを使わない方法で実装するのが一番簡単な対策だと思います。

簡単にまとめるとこんな感じかと。(他にもあるとは思いますが)

脅威対策
通信トレースによるcodeやclient_secretの漏えいCertificate Pinning
バイナリ解析によるclient_secretの漏えい難読化(限界あり)
Proxyサーバの通信ログよりcodeの漏えいPKCEの利用(Googleは既にPKCE対応してます)
client_secretの漏えいによるクライアントなりすましclient_secretを使わないフローの採用(implicit/Google Sign-In SDKの利用)



◆現バージョンのPokemon Goはどうなっているのか?

最近バージョンが上がったクライアントはどうなっているのか?を見てみました。

Proxyを挟んだ状態でアクセスするURLなどを見て推測すると、Google Sign-In SDKを使っているみたいです。また間にfiddlerを挟んだ構成だとログオンに成功しないので、MITMもチェックもしているみたいです。(うまくトレースできなかったので深追いはしていませんが)


◆PokeIVなどのアプリを使ってしまった場合の対策

しかし、一度PokeIVなどのアプリを使ってしまった場合、id_tokenやrefresh_tokenがアプリ側に保管されている可能性もあり、勝手にPokemon Goへ不正にアクセスされてしまう可能性もゼロではありません。

このような場合は、Googleアカウントのページからアプリケーションからのアクセスを一旦取り消して、正規のPokemon Goで再度サインインをしましょう。

アクセスを許可しているアプリケーション一覧が以下のURLで確認できるので、Pokemon Goを探して、一旦削除してしまいましょう。

https://security.google.com/settings/security/permissions



Pokemon Goを起動すると再度Googleアカウントへのアクセス許可のページが表示されますので、ここで改めて許可をすることでid_tokenが取得できるので引き続きPokemon Goを楽しむことが出来ます。

0 件のコメント: