よく知りもしないウェブサイトにOAuthで認証もどきをしてログインして回るというのは、そこら中に合鍵をばらまいて歩いていることになり、大変危険です。

Author: Nov Matake
Date:
よく知りもしないウェブサイトにOAuthで認証もどきをしてログインして回るというのは、そこら中に合鍵をばらまいて歩いていることになり、大変危険です。

非技術者のためのOAuth認証(?)とOpenIDの違い入門 : .Nat Zone

モバイルアプリを書いているプログラマはデバイスとサーバ間のコミュニケーションの、とくに確認/認証の部分を管理するやり方を知らない

Author: Nov Matake
Date:
モバイルアプリを書いているプログラマはデバイスとサーバ間のコミュニケーションの、とくに確認/認証の部分を管理するやり方を知らない

モバイルプログラマはセキュリティにルーズ–Cenzicがアプリ試験ツールを立ち上げ (via kyomichi)

“なんちゃら iOS SDK” でありそうな被害例

Author: Nov Matake
Date:

昨日の続き。「ソーシャルゲームなんて3000万人の特殊な人しかやってない」という意見もあるようなので、今日は iOS アプリ版。

登場人物

  • iOS SDK 出してるプラットフォーム
  • iOS SDK と連携するプラットフォームの公式 iOS アプリ
  • プラットフォーム上で “まっとうな” アプリを運営してる攻撃者
  • 攻撃者が自作した攻撃用アプリ
  • iOS SDK 使って開発された被害アプリ
  • あいかわらず無邪気な被害ユーザ

前提

プラットフォームが提供する iOS SDK は、

  1. プラットフォームが指定するカスタムスキーマ (ex. “xyz-connect://”) で始まる URI にアクセスすることで
  2. プラットフォーム公式 iOS アプリに access token 取得のフローを delegate し
  3. 公式アプリが被害アプリの指定するカスタムスキーマ (ex. “foobar-rowial://”) で始まる URI にユーザーを戻すことで、アプリに access token を返す。

被害アプリは、

  1. iOS SDK から受け取った access token を自身のバックエンドサーバに送り
  2. バックエンドサーバはプラットフォームが提供する Profile API (GET /me とか) にアクセスして
  3. レスポンスに含まれる user_id をもとにユーザを認証する。

シナリオ

  1. 攻撃者はプラットフォームが指定するのと同じカスタムスキーマで delegate を受け取る攻撃用アプリを自作する (なり誰かから買うなり..)
  2. 攻撃者は自分の iPhone/iPad に攻撃用アプリをインストール (xcode 経由だと、Apple の承認必要ないんですよね、たしか?)
  3. 攻撃者は自分が運営する “まっとうな” なアプリの DB から被害ユーザのアクセストークンを取って来て攻撃用アプリに埋め込む
  4. 攻撃者は被害アプリを起動して “なんちゃら ID でログイン” とかいうボタンを押す
  5. 被害アプリはプラットフォーム攻撃者が自作した攻撃用アプリに delegate 開始
  6. 攻撃用アプリは被害ユーザのアクセストークンを被害アプリに返す
  7. 攻撃者は被害ユーザのアカウントで被害アプリを使う

対策方法

プラットフォームの iOS SDK は “response_type=token code” に対応する。

被害アプリは、”response_type=token code” を使い、サーバーサイドへは access token ではなく authorization code を送る。(そしてサーバーサイドでは client authentication して code を token と交換する)

ただいかんせんプラットフォーム側の iOS SDK が対応してくれなかったり、既にアプリを公開していて古いバージョンもサポートしなければならなかったりすることもあるので、そういう場合はバックエンドサーバーで対応。

被害アプリのバックエンドサーバは、どうしてもアプリ側から access token を受け取らざるを得ないのであれば、昨日の記事と同様に access token 発行先アプリが自身であることを確認する。

追記

いくつか気になるtweetがあったので、載せときます。

「OAuth 2.0 (Implicit Flow) でログイン」の被害例

Author: Nov Matake
Date:

。登場人物

  • OAuth 2.0対応してる某ゲームプラットフォーム
  • 某ゲームプラットフォーム上で占いゲームを運営してる攻撃者
  • 某ゲームプラットフォーム上で運営されてる農園ゲーム(= 被害アプリ)
  • 某ゲームプラットフォーム上で無邪気に遊んでる被害ユーザ

※ 念のため、今回の話は特にゲームに限った話ではない。

前提

某ゲームプラットフォーム、農園ゲーム共に、XSS とか CSRF とかセッションハイジャックされるような脆弱性はない。

農園ゲームはプラットフォームが発行するAccess TokenをOAuth 2.0のImplicit Flowを使って受け取り、同じくプラットフォームが提供するProfile API (GET /me とか) にアクセスして、レスポンスに含まれる user_id をもとにユーザを認証している。

攻撃者は占いゲームのDBから任意のAccess Tokenを取得可能。

シナリオ

  1. 被害ユーザが占いゲームに登録 (= 占いゲームに対するAccess Tokenが発行される)
  2. 攻撃者が農園ゲームにアクセス、Authorization Flow開始
  3. 攻撃者が某ゲームプラットフォーム -> 農園ゲームへのRedirect Responseを中断させる
  4. 攻撃者がFragment中のAccess Tokenを占いゲームのDBから持ってきた被害者のAccess Tokenに置き換え
  5. 農園ゲームは受け取ったAccess Tokenをもとに、攻撃者を被害ユーザとして認証
  6. 攻撃者が被害ユーザとして農園ゲームで遊ぶ

対策方法

農園ゲームの開発者は、受け取ったAccess Tokenが農園ゲームに対して発行されたものであることを確認すること。占いゲームに対して発行されたAccess Tokenを受け入れないこと。

プラットフォームがFacebookの場合なら、以下のリクエストを行うことで、Access Tokenがどのクライアントに発行されたものかを検証可能。

GET /app
Authorization: OAuth replace_with_your_access_token

急募 : 他のプラットフォームの場合の対応策

参考文献