質問: ログイン認証無しの一般的なメールフォーム等の入力、確認、完了ページをセッションで管理する場合についてお聞きしたいので教えていただけないでしょうか。 セッションIDの保存にクッキーを使用しているのですが、 1 どのタイミングでセッションを再生成すればよいか。 現在は入力フォームに入った段階で、セッションスタート後すぐにsession_regenerate_idをしています。 その後、リロードした場合や確認ページから入力内容の編集で戻ってきた場合に指定秒経過ごとに再度session_regenerate_idをしています 2 セッションクッキーのタイムアウトについて 入力ページで決めうちでsession_set_cookie_paramsを使用し、expire属性に例えば3600(1時間)と設定するのが良いのか、もしくは、setcookieでページ遍移ごとに有効期限をリセットして延長する方法が良いのか、どちらが良いのか疑問です。 また、セッションクッキーには時間を設定せずに「 0(ゼロ) 」にした方がクッキーをクライアントのメモリのみに保存するので安全にも思います。 どうか、ご教授いただけないでしょうか。
回答: ご質問のテーマについては、以下の二種類の観点を持つことがよいと考えます。 (a)他に脆弱性がなくても単独で情報漏えい等が発生する脆弱性という観点 (b)他に(クロスサイトスクリプティングなどの)脆弱性がある場合に被害を緩和する観点 まず、(a)に関して言えば、ログインせずに、セッション変数で情報を持ち回りする場合、「ログイン前セッションIDの固定化攻撃」が成立する場合があります。 これは、セッションIDのクッキー(デフォルトではPHPSESSID)の値を外部の攻撃者にセットされた場合、そのセッションIDは攻撃者がわかっているので、セッション変数に値が入ったタイミングで攻撃者がサイトにアクセスすると、入力途中の値を攻撃者に閲覧される可能性がある、というものです。 それでは、セッションIDのクッキーを外部からセットする方法ですが、以下のようなものがあります。 1. クッキーモンスターバグによる方法(地域型JPドメイン名、都道府県型JPドメイン名を使用していて、IE利用の場合) 2. HTTPSを使用しているサイトで、通信路上に攻撃者がいる場合 クッキーモンスターバグとは、IEを利用していると、Set-Cookie時に domain=tokyo.jp など広範囲に適用されるクッキーが作れてしまう問題のことです。例えば、東京都のドメイン名は metro.tokyo.jp ですが、地方公共団体以外でも xxxx.tokyo.jp のドメイン名を持つサイトは非常に多いです。(Googleで site:tokyo.jp で検索してみてください)これらのサイト全てで、domain=tokyo.jpのクッキーを発行できる(ただしIEユーザのみ)ので、クッキーの汚染は現実的な問題になります。 HTTPSを利用している場合については下記の記事を参照ください。 * HTTPSを使ってもCookieの改変は防げないことを実験で試してみた HTTPSを使ったほうが危険になるのかと驚かれるかもしれませんが、そうではありません。HTTPSを使っておらず通信路上に攻撃者がいる場合は、クッキーの盗聴も改変も可能ですし、そもそも生の個人情報等も盗聴できるので、こちらは問題外ということになります。それを防ぐためのHTTPSであるわけですが、(クッキーの盗聴は防げるが)クッキーの改変は防げない、という問題です。 さて、ログイン前セッションIDの固定化攻撃を防ぐ確実な方法は、適切なタイミングでセッションIDを変更することです。そして、適切なタイミングを下記に示します。 * 秘密情報をセッション変数に格納する直前 このタイミングでセッションIDを変更すると、「攻撃者が知っているセッションID」には秘密情報は入らないので、確実な対策になります。 ログインを前提とするサイトの場合は、ログイン確認直後、かつセッション変数にログイン情報をセットする前にセッションIDを変更するべきですが、これも同じ理由です。 し・か・し・な・が・ら、ログインをしないケースでは、上記を実施しているウェブサイトはあまり多くないように見受けます。その理由は、セッションIDの固定化攻撃が成立する条件が厳しいわりに、攻撃により得られる「成果」があまり多くない(ログイン状態を乗っ取れるわけではない)ので、脆弱性を許容していると考えられます。(単に知らないだけという可能性ももちろんあります)。 一方、(b)に関しては、セッションタイムアウトの設定が有効です。こちらは、セッションのexpires指定による方法もありますが、より望ましい方法は、セッション変数として「最終クセス日時」を保存して、アクセスの度に確認することです。こうすれば、クッキーにはexpiresを指定しないため、クッキーがパソコンのファイルに保存されることもなくなります。