OAuth 2.0のstateとredirect_uriとOpenID ConnectのnonceとID Tokenについて

こんにちは、ritouです。

先日行われたidconのパネルディスカッションでOAuth 2.0のstateパラメータ、redirect_uriの扱いが取り上げられていました。

stateパラメータとは

こんな感じだと思います。

  • stateパラメータは何のためにあるの? : Client-Server-ClientのリダイレクトへのCSRF対策 draft-ietf-oauth-v2-31 - The OAuth 2.0 Authorization Framework
  • stateパラメータって必須? : RECOMMENDED draft-ietf-oauth-v2-31 - The OAuth 2.0 Authorization Framework. ServerはAuthorization Requestに含まれていたら必ずレスポンスに含む
  • stateパラメータには何の値を指定したらいいの? : セッションに紐づく値。HTML FormのCSRF対策に利用されるトークンをイメージすれば良いのでは
  • stateパラメータはワンタイムである必要はある? : ない CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例 | 徳丸浩の日記 ただし、OAuthのstateパラメータはServerにクエリパラメータとして渡るため、セッションIDそのものを指定するのはよくないと思う
  • 複数のOAuth ServerにAuthorization Requestを送りたい場合はstateパラメータはどう扱うべき? : (個人的には)Server単位で分けるべきな気がする
  • redirect_uriを前方一致とかにしたらstateパラメータ使わなくて良いのでは? : (カスタムURIスキームやlocalhostなどの話はあるが)redirect_uriを完全一致で判定することでオープンリダイレクタとして利用されるリスクを下げられる(と考えられている)

redirect_uriパラメータ

省略していいかという話でredirect_uriとの絡みが出てきます。
Draft 31ではこんな書き方がされています。

3.1.2. Redirection Endpoint

After completing its interaction with the resource owner, the
authorization server directs the resource owner's user-agent back to
the client. The authorization server redirects the user-agent to the
client's redirection endpoint previously established with the
authorization server during the client registration process or when
making the authorization request.

The redirection endpoint URI MUST be an absolute URI as defined by
[RFC3986] section 4.3. The endpoint URI MAY include an
"application/x-www-form-urlencoded" formatted (per Appendix B) query
component ([RFC3986] section 3.4), which MUST be retained when adding
additional query parameters. The endpoint URI MUST NOT include a
fragment component.

draft-ietf-oauth-v2-31 - The OAuth 2.0 Authorization Framework

んで、redirect_uriの扱いは各社わりとばらばらで、Client登録時には次のような登録のさせ方をしているサービスがあります。

  • 単一のURI
  • 複数のURI
  • クエリ含んだり含まなかったり
  • ドメインだけ登録してその配下ならredirect_uriに指定可能

個人的な意見でいうと、"redirect_uriにパラメータ指定できる"実装の場合でもstateパラメータのサポートはしていただけると、今後ライブラリが利用されるようになったときなど便利じゃないのかなと思います。
あんまり自由にさせすぎてオープンリダイレクタにさせられてしまうClientが出てきても困りますが、カスタムURIスキームの扱いなど課題はまだまだ残っている気がしますね。

stateパラメータに話を戻すと、OAuth Serverに一度は渡るわけですしAuthorization Responseについてきたからと言って厳密にはServerが作ったレスポンスかどうかわかりません。
ImplicitのAccess Tokenと同様に、stateパラメータも第3者に書き換えられる可能性があります。
まぁこれはOAuth 2.0の仕様なのでしょうがないですね。

おまけ:OpenID Connectなら!

OpenID ConnectのAuthorization Requestにはreplay atack防止のためにnonceパラメータというものがあります。

Spec obsoleted by openid-connect-core-1_0

  • ClientはnonceパラメータをAuthorization Requestに含む. Implicitの場合は必須
  • ServerはAuthorization Response内のID Tokenにその値を含む
  • ID Tokenには発行日時やServerの署名が含まれているため、client側はAuthorization Responseの検証が可能

response_typeにid_tokenを指定するとID TokenによりOAuth Serverがレスポンスを作成したことが確認できるのでちょっと便利です。
こういう細かいところで話が盛り上がれるのはidconならではだと思います。
小さいネタをLTとして持ち寄って議論のきっかけにするのも面白いかもしれません。

これ以外でOAuth 2.0の実装まわりで疑問などありましたら詳しそうな人たちに声をかけていただければと思います。
ではまた。

※2014/5/9 Covert Redirect関連で紹介されたので追記
response_type=codeを用いるケースでは、mixiが独自に導入したCSRF対策もあります。興味のある方は下記URLをどうぞ。
mixi Platformが導入したっていうOAuth 2.0のCSRF対策拡張を使ってみた - r-weblife