日向夏特殊応援部隊

俺様向けメモ

OpenID Provider のセキュリティ対策 (2) - return_to と realm のチェックを怠るな!

OpenID Provider のセキュリティ対策 (1) - まずは SSL を導入!話はそれからだ - Yet Another Hackadelicの続編です。

はじめに

RP が認証アサーションリクエストである checkid_setup/checkid_immediate を行う際には通常は return_to と realm を指定します。

return_to とは

OP から認証アサーションレスポンスを間接通信で受け取る際に戻って来るURLの事。RP が指定しておく。

realm とは

return_to のパターンをワイルドカードを使って表現する。

return_to と realm の検証

基本的に return_to の先は http://openid.art-code.org/handler であるという前提で。便宜上番号振りました。

(1) 期待通りの組合せ
realm
http://*.art-code.org
return_to
http://openid.art-code.org/handler

みたいな組合せの場合、realmで指定したパターンにreturn_toはマッチするので特に問題は無い。

(2) realm の指定がワイルドすぎる
realm
http://*.org
return_to
http://redirect.example.com/redirect?url=openid.art-code.org/handler

かなり広範囲にワイルドカードが指定してあるケース。これはダメ。

(3) realm に違反する return_to

例えば、

realm
http://*.art-code.org
return_to
http://redirect.example.com/redirect?url=openid.art-code.org/handler

これは反してるのでNGになるはず。

(4) realm/return_to は正常だがRPとは異なるホストに適用してある

さらに言うと、

realm
http://*.example.com/
return_to
http://redirect.example.com/redirect?url=openid.art-code.org/handler

だったら見かけ上OKだけど、普通に考えてOPとしてこれを許可する訳には行かない。
そもそも RP から見てまったく違うホストに対して realm も return_to も指定してあるので、こういうケースは信じるべきではない。

国内OPの対応状況

○は良く出来ました。×はダメ。△は微妙。解説はこの後で。

-- Yahoo! Japan livedoor hatena wassr openid.ne.jp
(1) × × ×
(2) × × × ×
(3)
(4) × × ×

Yahoo! Japan の場合

(1) の場合 -> ○

のような形で realm も return_to も明示してる。これがお手本。

(2) の場合 -> ○

こんな感じで怒られた。これがあるべき姿。さすが Yahoo! ですな。一点だけ言えば openid.mode=error で返してもいい気がするけど、敢えて返さないようにしたんですかね。

(3) の場合 -> ○

(2) と同じ画面で怒られる。これも正しい。間接通信でレスポンスが戻ってこないのも (2) と一緒。

(4) の場合 -> △

これは正常であると認められてリダイレクタに飛ばされます。この議論は別途。

livedoor の場合

(1) の場合 -> ○

これはまぁOKです。ただ realm も一緒に出すとなお良いです。

(2) の場合 -> ×

(1) と同じように出た件。これは openid.mode=error でレスポンス返すなり Yahoo! と同じようにエラー画面出して戻さないとかやるべき。

(3) の場合 -> △

そもそも画面真っ白で何も出ない。結果的にrejectされたから△としておく。

(4) の場合 -> △

一応 return_to 見て分かる人はリダイレクタだと分かるから△としておく。でも素人は分からないよねぇ。

hatena の場合

(1) の場合 -> ×

realm だけ出すってのは宜しくない。return_to と共に出さないと中間者攻撃の餌食になる可能性があります。

(2) の場合 -> ×

以下のサイトでとして「*.org」ってどんだけのサイトに許可すんだよw

(3) の場合 -> △

どうやら hatena では Data::Dumper を使っている模様><
まぁ結果的にその先に進まないから△だけどこれは恥ずかしい><

(4) の場合 -> ×

realm だけしか出してないので、その先にリダイレクタが経由してあるなどユーザーに気づかせるきっかけなど一切無し。

wassr の場合

(1), (2), (4) -> ×

(3) 以外だと全部、

みたいになってる。「」の中が空っぽorz...

(3) の場合 -> △

真っ白><

openid.ne.jp

(1), (2), (4) の場合 -> ×

realm しか出してない。return_to も出して下さい><
あと、(2) は reject しないとダメ。

(3) の場合 -> ○

これは見事に error を返してる。ちょっと意外*1だった。

と言う訳でまとめますよ!

  • 認証確認画面では return_to, realm 共に明示する
  • realm に不一致な return_to に対しては openid.mode=error で返すか、リダイレクトしない
    • リダイレクトしない方が賢いかも*2

リダイレクタとrealmの検証については別途エントリ書こうと思います。(続く)

*1:失礼しましたw

*2:そのRPが悪意のあるRPだったら返さない方がいいと言う考え方