TwitterのOAuth認証を使ったサービスを開発する際の注意

OAuth を使ってソーシャル・ネットワーキング Web サイトにアクセスする: 第 2 回: OAuth 対応のWeb 版 Twitter クライアントを作成する」のサンプルをいじくっていて気づいたんですが、TwitterOAuth認証を使ったサービスを開発する場合、AccessTokenの管理方法に注意が必要です。
あんまり自信がないので、誤りがあればどんどん指摘してください。

以下の条件が成り立つ場合、サービス内でなりすましができてしまいます。

  1. サービス(Consumer)がtwitterIDとAccessTokenをひもづけて保管している。
  2. サービスがブラウザへ渡すcookieにtwitterIDをそのまま保存している
  3. ブラウザからサービスへtwitterIDを含むCookieが渡された場合、twitterIDをキーとしてサービス内に保存しているAccessTokenを検索し、存在していれば認証済みであるとみなす。
  4. なりすまし対象のアカウントがすでにOAuth認証済みで、サービス内になりすまし対象アカウントのAccessTokenが保存されている。

想定されるシナリオ

"サービス"はtwitterAPIを利用するWebアプリケーションです。
"Alice"(通常のユーザ)と"Carol"(なりすまし攻撃者)がいて、AliceがTwitterAPIを利用するサービスにOAuthで許可を与えたとします。

twitterからサービスへAlice用のAccessTokenが送信され、サービスはAliceのtwitterIDとひもづけて保存します。
twitterの認証画面からサービスの画面に戻った時に、サービスからAliceのブラウザにtwitterIDを含むcookieが送信されます。

次にAliceがサービスにアクセスした際に、サービスはcookieからtwitterIDを取得し、そのIDに対応するAccessTokenを取り出します。対応するAccessTokenが存在していれば、サービスはAliceがOAuthで許可を与えているものと見なします。

Carolはサービスにアクセスする際にAliceのスクリーンネームからtwitterIDを割り出し、AliceのtwitterIDを含むcookieを偽造することでサービス内でAliceになりすますことができます。

twitteIdはintの数値であり、これはTwitterAPIを使うことでスクリーンネームから容易に取得できます。ブラウザから確認したいのであれば、Twitter API Viewerのサービスを使ってみてください。

対策

サービス内でAccessTokenを保存する際のキーや、cookieに保存する値として適切なのは、以下の条件を満たすものです。

  • 容易に予測不可能
  • 一意で、ハッシュ値のように衝突しない

最後にひとこと

今後、このような事故がおこった場合、「OAuth認証によってパスワードによる認証が無くなってしまったため、これまで安全と思って送受信したり保存したりしていたIDがセキュリティ上の弱点となってしまった事例」とか言われるんだと思います。
これからOAuth対応でいろいろ手が入るサービスが出てくるでしょうが、気になる人はcookieにtwitteridが入っていないか注意してください。