質問: 会員サイトで一般ユーザーがアクセスできるすべてのページで自動ログインを実装しようと思っているのですが、自動ログインはしたことがなくて処理を洗い出してみたのですが、セキュリティー的な観点でだめなところやこうした方がいいなどありましたら教えていただけるとありがたいです。 ※クッキーの有効期限やセキュアなどはシステム側で指定します。(fuelphpです) ``` クッキーがない場合 ログイン画面へ遷移させる ログインする ログインに使用したアドレスとパスワードがDBに存在するか確認する 存在する場合 ログインに使用したアドレスとパスワードを組み合わせてハッシュ化する そのハッシュ値をクッキーに保存する セッションを張って、トップページへ 存在しない場合 ログイン画面へ戻りそんな会員いねえよという クッキーがある場合 クッキーに保存されているハッシュ値と、DBに保管されているアドレスとパスワードを組み合わせたハッシュ値が存在するか確認する。 一致する場合 ハッシュ値からアドレスとパスワードを復元し、自動ログインする セッションを張って、指定ページを表示 一致しない場合 アクセス端末の情報と位置情報と改竄回数を取得しDB保存 改竄回数が3回以内の場合 クッキーを改竄している可能性があるとみなし、警告画面を表示させる 改竄回数が3回以上の場合 なにかしらの処理 ``` 修正後 ``` ■説明に必要なテーブル user id name surname mail password user_token (パスワード変更時に新規token発行とパスワード記録) id user_id pwssword token limit ■おおまかな処理 クッキーがない場合 ログイン画面へ遷移させる ログインする ログインに使用したアドレスとパスワードがDBに存在するか確認する 存在する場合 ログインユーザーが所持するパスワードのトークンを取得 そのトークンをクッキーに保存する セッションを張って、トップページへ 存在しない場合 ログイン画面へ戻りそんな会員いねえよという クッキーがある場合 クッキーに保存されているトークンと、user_tokenにそのトークンが存在するか確認する。 存在する場合 user_tokenから遡りアドレスとパスワードを探し、自動ログインする セッションを張って、指定ページを表示 存在しない場合 アクセス端末の情報と位置情報と改竄回数を取得しDB保存 改竄回数が3回以内の場合 クッキーを改竄している可能性があるとみなし、警告画面を表示させる 改竄回数が3回以上の場合 なにかしらの処理 ```
回答: ここですが、 > > ハッシュ値からアドレスとパスワードを復元し、自動ログインする > > > ハッシュ値から元の平文は復元できませんが、おそらくDBからアドレスとパスワードを求めるという意味だと解釈しました。これなら可能ですよね。 それは良いのですが、以下がよくありません。 > > ログインに使用したアドレスとパスワードを組み合わせてハッシュ化する > > > この方法ですと、ハッシュ値は、パスワードを変更しない限り同じものになります。そうすると、ハッシュ値の有効期限を設定することができなくなりますし、ハッシュ値があればいつでもどこからでもログインできるので、そういうむやみに強力なものをクッキーに保存することは好ましくありません。 なので、ハッシュではなく、トークンを使います。トークンは、要は乱数ですね。提示いただいた処理は、概ねハッシュを使わなくてもトークンでも実装できます。考えてみて下さい。 トークンは、有効期限を設けることができます。有効期限はデータベースに保存しておきます。また、何らかの問題が発生した場合は、トークンの無効化も簡単にできます。 追記します。トークンですが、単純化した実例を書いてみます。 | メールアドレス | トークン | 有効期限 | | --- | --- | --- | | tanaka@example.jp | 5b9636a4 | 2017/12/31 | | sato@example.jp | NULL | NULL | | takahashi@example.jp | a4f84d89 | 2017/12/01 | | yamada@example.jp | NULL | NULL | ログインに成功したら、トークンをクッキーとして出力するとともに、DBには上記のように記録しておきます。これで分かりませんか?