オープンリダイレクタを脆弱性とみなすべきかは議論が分かれるところです。Google等の一部のサイトは、自サイトのオープンリダイレクタを脆弱性としてはみていません。一方で、脆弱性検査の現場では、見つかれば脆弱性として報告することが多いと思います。
その辺の議論はおいておいて、オープンリダイレクタの検査は、ブラウザの特性もからんで意外とバリエーションが多くて面白いので、本日の日記で取り上げてみたいと思います。
大まかにいうと、リダイレクトは、302応答のLocationヘッダ、Refresh(HTTPヘッダ、METAタグ)、JavaScriptによるものがありますが、本日は302応答のLocationヘッダのリダイレクタについて取り上げます。
パターン3:Locationヘッダの先頭に値が入る場合
こんなケースです。一番良く見るパターンです。
Location: {$u}
$uの正常な値は "http://www.hatena.ne.jp/foo/" で、LF(%0A U+000A)は使えないとします。
外部にリダイレクトしないように、パラメータuの値を何らかの方法でチェックしていても、それが不完全ならば下の3A、3Bが通ってしまうかもしれません(このような値が通ることは少なくありません)。
■3A: redir.cgi?u=http://www.hatena.ne.jp.example.com/foo/
→ Location: http://www.hatena.ne.jp.example.com/foo/
■3B: redir.cgi?u=http://example.com/http://www.hatena.ne.jp/foo/
→ Location: http://example.com/http://www.hatena.ne.jp/foo/
元のURL(http://www.hatena.ne.jp/)のサブドメイン(www)の箇所のチェックが不完全ならば、下の3Cが通ってしまうかもしれません。
■3C: redir.cgi?u=http://example.com?.hatena.ne.jp/foo/
→ Location: http://example.com?.hatena.ne.jp/foo/
「パターン1:サブドメイン部分に値が入る場合」で見たように、上の3Cの "?" の箇所を、";", "#", ":80", "\", NULL, CR などに変えるバリエーションがあります。
先頭が "/" で始まる値が許容される場合は、下の3Dのような検査パターンが通るかもしれません。
■3D: redir.cgi?u=//example.com/foo/
→ Location: //example.com/foo/
「パターン2:スラッシュが先頭に付けられる場合」でみたように、上の3Dの "/" を "\" にするなどのバリエーションがあります。
テストしたブラウザ
IE8、Firefox3.6、Opera10、Safari5、Chrome9(いずれもWindows Vista版)。