PEAK XOOPS - 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1 in englishin japanese

Archive | RSS |
PHP
PHP : 「プログラミング解説書籍の脆弱性をどうするか」への反論のようなもの1
Poster : GIJOE on 2006-01-21 05:25:51 (32538 reads)

in englishin japanese
拙著「PHPサイバーテロの技法」に脆弱性がある、という高木浩光氏のブログがあります。

最初ざっと見たときには、「どんな書籍でも悪意を持って読めば叩き方はいくらでもあるのだな」くらいにしか思っていなかったのですが、他の方のサイトのブログなどを読むと、結構引用されていることが多く、あらためて読んでみたところ、事実として、拙著の記述にミスがあったので、まずはそのことについて書きます。

Quote:

ただし、 p.67のCSRF対策などには問題がある。「対策4」として、

Quote:
管理者セッション内の各種データの受け渡しに、$_GET や $_POST ではなく、 $_SESSION を利用する。


という手法が挙げられていて、これが本命の対策のように書かれているが、これは対策にならない。4月27日の日記に書いていたように、必要なパラメタ値がセッション変数にセットされているということは、前のどこかのページでその値をセットするリクエストがあるはずで、そのリクエストにCSRF攻撃した後に実行ページにもCSRF攻撃するような仕掛けで破られてしまう。

確かに「破られる」部分についてはその通りです。「CSRF対策には、本命と呼べるものが存在しない」ということを説明するためには、なるべく多くの対策法を書くべきだろうと思い、頭の中で簡単にシミュレートしただけのものを載せてしまいました。セッション継続中に、JavaScriptによる連続自動POSTをされるようなサイトに行くことがあれば、対策にはなりません。攻撃側のハードルを高めることにはつながっていますが、せいぜい、「POST利用法」と同程度の「補助的な手法」にすぎません。

高木氏の指摘に感謝すると共に、誤った情報を記載してしまったことを、読者の皆様にお詫びいたします。

ただ、「本命の対策のように書かれているが」という部分はかなり恣意的です。

書籍をお持ちでしたら、該当ページをご覧いただけば良いでしょうし、お持ちでない方も、Amazonでの「なか見検索」もはじまったので、CSRFで検索すれば、該当ページを見ることができるはずです。

「対策1〜4を並行して実施」と最初に書いてあり、その4通りの方法すべてに、メリットとデメリットを書いてあります。P.44には「対策が難しいが故に、いろいろな方法を組み合わせなければいけないのが、対CSRF防御の特徴です」とさえ書いてます。


また、ここからは反論に近いのですが、JavaScriptによる連続自動POSTをされるようなサイト(悪意があるサイトというより、脆弱なサイト)にセッション継続中に訪問することがある、という前提であるなら、高木氏が4/27に書いた対策法も、対策としては不完全です。

Quote:

簡潔な対策方法

Webアプリケーションに対してデータ変更を処理させるページ(前述の「3ページ目」)の前のページ(前述の「2ページ目」)に以下のHTML要素を含ませる。



そして、「3ページ目」で、そこに送信されてくるこの値が、cookieのその値と一致しているかを調べて、一致しているときだけ処理を実行する。

「セッション追跡用cookieの値」には、前述の(A)方式ならばセッションIDの値、(B)方式ならばユーザIDとパスワード(のハッシュ値など)の両方を格納し、「3ページ目」でそれぞれの一致を確かめる。

第三者サイトから「3ページ目」へのハイパーリンク(JavaScriptによる自動 POSTを含む)が作られても、一致させる値を予測することは不能であるはずなので、CSRF攻撃は成功しない。

前述の(A)というのは、いわゆるPHPセッションのことだと思われますが、そうであれば以下の方法で破ることができます。

- セッション固定をしかける
- そのセッションが生きた状態でユーザがログインしてしまう(セッションIDは変わらない)
- セッションIDもPOSTにつむCSRFをしかける

もちろん、
- ログインした時点で、セッションIDを変えるようにする。
- ログインしない限りセッションは開始しない
- session.use_only_cookies を on にする
いずれかの方法で、この攻撃は防げますが、この4/27の日記にはどこにも触れられていません。(ログインを行わないアプリケーションについて、session fixationの記述はありますが)

おそらく高木氏は「ログイン処理する時に新たなセッションIDを発行するのなんてのは当たり前じゃないか」などと反論するのでしょうが、ここで重要なのは、ログイン処理を行っても明示的にセッションID変更をやらないとセッションIDが生きたままであることと、session.use_only_cookies のデフォルトはoffであること、の2点です。

また、それとは別の理由で、セッションIDをそのままHTML中に出力してしまうのは、あまり好ましくありません。なんらかのプロクシ・キャッシュに残る可能性があるからです(HTTPヘッダにキャッシュ不可と書いてあったとしても)。せっかくクッキー(HTTPヘッダ部)だけにとどめている情報を、わざわざHTML(HTTPコンテンツ部)に出力する理由が判りません。

ワンタイムチケット(トークン)のコードなら4/27の時点でも、ちょっと探せばいくらでも見つかったはずです。セッション必須という点でも、特にワンタイムチケット法より優れているとも思えません。なぜわざわざ危険性の高い方法を勧めるのか、疑問でなりません。

ともあれ、ここでは、間違いの訂正という意味合いだけにとどめます。
ご指摘どうもありがとうございました。

0 comments
Printer friendly page Send this story to a friend

Comments list

Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!