だ。ログ。

開発とかスノボとかやきうとか。

EC-CUBE3のパスワードリマインダの脆弱性のとりあえずの回避を行う

blog.tokumaru.org

徳丸浩先生が古い記事で上げていたパスワードリマインダがダメな理由。と言う記事を見てそう言えばEC-CUBEもリマインダ自体はメールアドレスを入力して、そのメールアドレスにリマインダメールを発射する仕組みになっている事に気付く。
総当り攻撃でメールアドレスを入力しまくってレスポンスの時間を推測すれば、ある場合と無い場合のレスポンス時間により、このメールアドレスはEC-CUBEのデータベース上に登録されている。と言う推測が出来てしまう。

1. 使わない

そのまんま。メールでのパスワードリマインダは使わない。
潔し。男気にあふれる選択。
ホントはこれに尽きる。パスワード忘れたらお問い合わせフォームからどうぞ。と。

2. 改修

んで本題。
徳丸先生の記事からすると、EC-CUBE3はセキュリティ的にいかんぞ。と。
本当だとパスワードの再設定は1回のみにしておくのが望ましい。またパスワードリマインダ使いました。と言う通知を何らかの方法で行う。と言う部分が必要になるかと思われる。

ただ、ここまでの要件を実装するとなると色々と改修が入る為、回避策と言う訳ではないが有効期間を持たせる形にしてみる。
/src/Eccube/Controller/ForgotController.php 90行目付近

            } else {
                log_warning('Un active customer try send reset password email: ', array('Enter email' => $form->get('login_email')->getData()));
            }
#ここにCookieで任意のデータを登録する
            setcookie("hogehoge", "fugafuga", PASSWORD_DEFAULT),time()+3600,"/forgot");
            return $app->redirect($app->url('forgot_complete'));

上記の場合、利用後1時間はパスワードリマインダを使いました。という記録を残す。と言うロジック。
ただCookie部分は適当に作っているが、本当であれば推測され辛いデータに形成しておくべき。
またリスクとしてはCookie削除すれば結局使えてしまう。またクローラースパイダー等のツールを使ってcookieを持たないツールの場合は無力。
そう考えると本当は実行した回数をカウントして保持して異常値を叩き出したら再発行を一旦停止する。と言う事も必要かもしれない。
これはモヤモヤと考えているだけだが、forgotコントローラが動いた段階で指定した時間のしきい値以上のリマインダが叩かれたらエラーページや申し訳ありませんが現在混雑中です。みたいな表示で逃げる。ってのもありかな。と。

んで、話しを戻してCookieを使った場合。
今度はこのCookieの値が存在した場合はindexコントローラのrenderに値を持たせて

<p><button type="submit" class="btn btn-primary btn-block">次のページへ</button></p>

を制御する。見せないとかボタンが押せないとかその辺でいいと思う。