TwitterのOAuth認証を使ったサービスを開発する際の注意(その2)

前回のエントリで、対策が具体的でなかったのは、SHA-1などのハッシュ関数を使っても問題ないか自信が持てなかったためです。すみません。とりあえず自分で納得できる対策が調べられたと思うので書いておきます。

twitterIDをそのままSHA-1などの暗号学的ハッシュ関数にかけただけでは弱いので避けるということは知っていましたが、単なる固定文字列のsaltを付け加えるだけだと、常に同じ値が生成されるのでこれでいいのか自信が持てませんでした。

で、調べてみたら自動ログイン用のクッキーの値に必要な特性は、セッションIDの特性によくにていて、値の生成は「ユーザIDや時刻等の情報と擬似乱数とを混ぜ合わせた文字列に対してハッシュ関数を使用する」で問題なさそうだということが分かりました。
また、管理方法もに似ていて、「ログインごとに認証用のキーとなる値を新しい値に更新しなければいけない」ということも分かりました。

以下の情報を参考にしました

「解答:まちがった自動ログイン処理」で参考にした箇所

セキュリティのベストプラクティスとしてはクッキーにユーザに関連するいかなる情報(暗号化された情報を含む)も保存すべきではありません。クッキーにユーザに関連した情報(ユーザID、パスワード、メール、氏名、etc)を保存しなければならないシステムである場合、設計を見直し、ユーザ情報をクッキーに保存しなくても良い設計にしなければなりません。クッキーに保存しても良い値は、表示設定などのユーザ情報と関係の無い情報、セッションIDなどの予測不可能なランダムな値のみです。

ユーザIDくらいは大丈夫かと思ってたけど、そうだったのか。

【まとめ】

  • 自動ログイン機能は基本的にセキュリティ上のリスクを増加させるので安全性が重要なサービスでは実装しない。
  • 自動ログインの実装にはセッション管理と同様にランダムなクッキーの値を使用する。
  • 自動ログイン用のクッキーはログインの度に新しい値に更新する。(古い鍵の削除も忘れない)
  • ログイン時に自動ログインオプションが無効かつ自動ログイン用のクッキーが設定されている場合は自動ログインテーブルの該当レコードと自動ログインクッキーも削除する。
  • 自動ログイン用のクッキーは自動ログイン処理を行う場合にのみ必要なので自動ログイン専用のディレクトリを設定し、そのディレクトリのURLがリクエストされた場合にのみ送信する。(XSSリスクの低減)
  • ログアウトした場合、自動ログインクッキーが設定されている場合、自動ログインテーブルの該当レコードと自動ログインクッキーも削除する。
  • 実際の運用では古い自動ログイン用のレコードが溜まるので定期的に不要なレコードを削除する。

「安全なウェブサイトの作り方」で参考にした箇所

1.4 セッション管理の不備」が参考になった。
以下は項目名だけ抜粋

1) セッション ID を推測が困難なものにする
2) セッション ID を URL パラメータに格納しないようにする
3) HTTPS 通信で利用する Cookie には secure 属性を加える
4-1) ログイン成功後に、新しくセッションを開始するようにする
または
4-2) ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移毎にその値を確認する

IPA セキュア・プログラミング講座:Webアプリケーション編」で参考にした箇所

自動ログイン用のキーの特性として、セッションIDと同じ特性が必要らしいので、「第4章セッション対策セッション乗っ取り:#2 セッションID強度を高める」が参考になった。

(1) 公共に知られていそうなIDは使用しない
例えば、会員番号やユーザID等、公共に知られていそうな値では容易に推測が可能であるので、使用すべきではない。セッションIDは、人間が覚えておく必要は無いので、見た目が無意味な値であっても、まったく問題はない。

(2) ランダムなIDを使用する
00001、00002...等の規則性や連続性のある値は、推測が容易であるのでランダムなIDを使用する。例えば、ユーザIDや時刻等の情報と擬似乱数とを混ぜ合わせた文字列に対してハッシュ関数を使用することで、ランダムなIDが生成されるようになる。
ただし、擬似乱数生成関数やハッシュ関数を自前で作成することは避けるべきである。

(3) 桁数と文字種を多くする
桁数が短く、文字種の少ない場合、ブルートフォースアタックで破られてしまうおそれがある。これを防ぐためには、使用する文字種、桁数をなるべく多くし、総当りするパターンを増やすことである。例えば、英数小文字大文字で20桁の値を考えた場合、組み合わせとしては「(26+26+10)^20」通りとなる。

(4) ユニークなセッションIDを発行する
セッションIDは、どのような場合でも、常にユニークな値を発行するようにする。

  • Webアプリケーションを利用する他ユーザに対して発行する場合

同じセッションIDを発行してしまうと「なりすまし」のおそれがある。

  • 同一ユーザに対して発行する場合

セッションの度に同じIDを発行することがないようにする。これは一度セッションIDが盗まれてしまうと、Webアプリケーション内での「なりすまし」が永続的に可能となってしまうからである。

IPAの資料には、セッション設計のガイドラインはあるけど、自動ログインについての記述が無かったので、追加して欲しいと思った。