この文書は2016年以降更新されていません

パスワードを忘れた場合に関するチートシート

OWASP 作成
ジャンプ先: 移動検索
Cheatsheets-header.jpg

最終改訂日 (yy/mm/dd):2015/09/15

はじめに

この資料では、Web アプリケーションの "パスワードを忘れた場合" 機能を実装する際の基準となるシンプルなモデルを紹介します。

問題点

パスワードを忘れた場合の機能の実装については、業界標準が存在しません。その結果、電子メールや特殊な URL、一時パスワード、個人的な秘密の質問など、アプリケーションごとにさまざまな手続きをユーザーに強いる状況になっています。既存のパスワードを回復できるアプリケーションもあれば、新しい値にリセットしなければならないものもあります。


手順

手順 1) 個人識別データと秘密の質問を収集する

セキュアな、パスワードを忘れた場合機能の 1 ページ目で、以前に (通常はユーザーの初回登録時に) 収集した複数のハード データの入力をユーザーに求めます。この手順については、「秘密の質問の選択と使用に関するチートシート」の個人識別データに関するセクションで詳しく説明されています。

少なくとも、手順 3 で使用することになる、パスワードリセット情報を何らかの帯域外サイドチャネルに送信するためのデータを収集しておく必要があります。たとえば、電子メールアドレス、SMS テキスト番号などです。

手順 2) 秘密の質問を検証する

手順 1 のフォームが送信されたら、指定されたユーザー名に対して各データが正しいことをアプリケーションで検証します。何か誤りがあった場合や、ユーザー名が認識できない場合は、2 ページ目に「申し訳ありませんが、データが正しくありません」などの一般的なエラーメッセージを表示します。送信されたすべてのデータが正しければ、手順 2 として、ユーザーがあらかじめ設定した個人的な秘密の質問を 2 つ以上と、回答用の入力フィールドを表示します。回答用の各フィールドを単一の HTML フォームに組み込むことが重要です。

回答する質問をユーザーに選択させるドロップダウンリストは用意しないでください。このページ上のフォームを送信するときに、ユーザー名を (非表示か表示かにかかわらず) パラメーターとして送信しないでください。ユーザー名は、必要に応じて取得できるようにサーバー側セッションに格納しておきます。

通常、ユーザーの秘密の質問と回答に含まれるエントロピーは、適切に選ばれたパスワードより少ないため(「お気に入りのスポーツ チームは?」や「出身地はどこですか?」といった典型的な秘密の質問に対して想定される回答はいくつあるでしょうか?)、回答の試行回数を必ず制限してください。ユーザーがしきい値 (3 ~ 5 回程度) を超えた場合は、そのユーザーのアカウントを適正な期間 (約 5 分以上) ロックアウトした後、標準的な多要素ワークフローに従って何らの形のチャレンジトークンでユーザーを試します (次の手順 3 を参照)。これにより、ハッカーが回答を推測してユーザーのパスワードをリセットする試みを軽減できます。(ユーザーの電子メールアカウントが既に破られているとも考えられるので、電子メールを含まないトークン、たとえば SMS やモバイル ソフトトークンなどが最善です。)

手順 3) トークンをサイドチャネル経由で送信する

手順 2 の直後にユーザーのアカウントをロックアウトします。次に、SMS を送信するか、ランダムに生成した 8 文字以上から成る、他の何らかの多要素トークンチャレンジを使用します。これにより、"帯域外" の通信チャネルが導入されます。これは、ハッカーにとって、乗り越える必要があるさらなる障壁となるので、多層防御が追加されたことになります。ハッカーがどうにかして手順 1 と 2 を首尾よく通過したとしても、サイドチャネルを突破する可能性は低いでしょう。また、システムで生成するランダムコードの有効期間を限定するのもよい考えです (たとえば 20 分以下など)。これにより、ユーザーが電子メールの確認を怠り、後でその電子メールアカウントが破られてしまった場合、ユーザーが自分のパスワードをリセットせず、"リセット用パスワード" トークンが攻撃者に漏れてしまっても、パスワードのリセットに使用するランダムトークンが既に無効という事態になります。言うまでもなく、ユーザーがパスワードをリセットしたら、ランダムに生成したトークンを必ず無効にする必要があります。

手順 4) ユーザーが既存のセッションでパスワードを変更できるようにする

手順 4 では、手順 2 でチャレンジ質問が回答された既存のセッションで、手順 3 で送信したコードを入力するよう要求し、ユーザーがパスワードをリセットできるようにします。コードの入力フィールド、新しいパスワードの入力フィールド、および新しいパスワードの確認用の入力フィールドを備えたシンプルな HTML フォームを表示します。正しいコードが入力されたことを検証するとともに、アプリケーションの他領域に存在するパスワードの複雑度に関する要件をすべて満たすように強制します。前述のとおり、フォームの送信時にユーザー名をパラメーターとして送信しないでください。最後に、ユーザーが手順 1 と 2 を正しく完了せずに、この最後ステップにアクセスするのを防ぐためのチェックが不可欠です。このチェックを怠ると、強制ブラウジング攻撃が可能になるおそれがあります。

手順 5) ロギング

パスワード変更リクエストが送信されたときに監査記録を取ることが重要です。これには、秘密の質問が回答されたかどうか、リセットメッセージがいつユーザーに送信されたか、リセットメッセージをいつユーザーが使用したかの記録が含まれます。特に、秘密の質問への回答に失敗した試行と、失効したトークンの使用に失敗した試行のログを記録しておくことが重要です。このデータを使用して悪用や不正な挙動を検出できます。時刻、IP アドレス、ブラウザー情報などのデータを利用して、不審な使用の傾向を突き止めることができます。

その他の考慮事項

  • パスワードが正常にリセットされたら、そのセッションを無効にして、ユーザーをログイン ページに転送してください。
  • リセットに使用する質問の強度は、資格情報の種類によって変える必要があります。管理者の資格情報には、より高度な要件が必要です。
  • 理想的な実装では、自動化を回避するために、尋ねる質問を周期的に変えます。


Authors and Primary Editors

Dave Ferguson - gmdavef[at]gmail.com
Jim Manico - jim[at]owasp.org
Kevin Wall - kevin.w.wall[at]gmail.com
James McGovern - james.mcgovern[at]hp.com
Wesley Philip - wphilip[at]ca.ibm.com


Other Cheatsheets

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets