web-dev-qa-db-ja.com

「パスワードを忘れた」実装の最良の方法は?

「パスワードを忘れた」機能を実装するための最良の方法を探しています。

私は2つのアイデアを思い付きます:

  1. ユーザーがパスワードを忘れた場合、ユーザーはユーザー名、メールアドレス、そしておそらく生年月日または姓を入力する必要があります。その後、一時パスワードを含むメールがユーザーのメールアカウントに送信されます。ユーザーは一時パスワードを使用してログインし、パスワードをリセットします。

  2. 同様ですが、メールにはユーザーがパスワードをリセットできるリンクが含まれています。

または、誰かが私にもっと安全な方法を提案できますか?また、一時的なパスワードまたはリンクを送信し、24時間以内にユーザーにパスワードをリセットするように強制します。そうしないと、一時的なパスワードまたはリンクが使用できなくなります。どうやってするか?

143
Hoe Chin

更新:より良いアプローチのために2013年5月に改訂

  1. ユーザーはユーザー名を入力し、「パスワードを忘れた」を押します。ユーザー名も忘れられることがあるため、ユーザー名の代わりにメールアドレスを入力するオプションもお勧めします。
  2. システムには、列IDTime、およびUserIDを持つテーブルpassword_change_requestsがあります。新しいユーザーがボタンを押すと、テーブルにレコードが作成されます。 Time列には、ユーザーが[パスワードを忘れた]ボタンを押した時刻が含まれます。 IDは文字列です。長いランダム文字列(GUIDなど)が作成され、次にパスワードのようにハッシュされます(それ自体が個別のトピックです)。このハッシュは、テーブル内の「ID」として使用されます。
  3. システムは、リンクを含む電子メールをユーザーに送信します。リンクには、元のID文字列も含まれます(ハッシュ前)。リンクは次のようになります:http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF。 forgotpassword.jspページはIDパラメーターを取得できるはずです。申し訳ありませんが、私はJavaを知らないので、これ以上具体的に説明することはできません。
  4. ユーザーがメール内のリンクをクリックすると、ページに移動します。ページはIDをURLから取得し、再度ハッシュし、テーブルに対してチェックします。そのようなレコードが存在し、たとえば24時間以内であれば、ユーザー新しいパスワードを入力するプロンプトが表示されます
  5. ユーザーは新しいパスワードを入力し、[OK]を押すと、誰もが幸せに暮らします...次回まで!
174
Vilx-

それはすべてあなたのサイトとあなたが達成しようとしているセキュリティのレベルに依存しますが、ウェブアプリの基本的なプロセスは次のようになります:

  1. ユーザーは「パスワードを忘れた」ページに移動し、ユーザー名または電子メール(一意のいずれか)を入力してパスワードのリセットを要求します。

  2. 必要に応じて、この段階で、事前に定義されたセキュリティの質問への回答や生年月日などの追加情報を要求することにより、要求を確認できます。

  3. ユーザーのアカウントを検索します。アカウントレコードに対して一時パスワード(通常はGUID)とタイムスタンプを保存します。一時パスワードを含むメールをユーザーに送信します。

  4. ユーザーは、メール内の一時パスワードとユーザーの識別子を含むリンクをクリックするか、「パスワードを忘れた」ページに移動して、一時パスワードとその識別子をコピーして貼り付けます。ユーザーは新しいパスワードを入力して確認します。

  5. ユーザーのレコードを検索し、現在の時刻が手順2で保存したタイムスタンプの指定された制限時間(1時間など)内にある場合、新しいパスワードをハッシュして保存します。 (明らかに、一時パスワードが一致する場合のみ!)。一時的なGUIDおよびタイムスタンプを削除します。

ここでの原則は、ユーザーにパスワードをメールで送信することですchange。最初に保存されたパスワード(ハッシュする必要があります!)は、ユーザーが覚えている場合に備えて一時的なパスワードに変更されることはありません。

元のパスワードはハッシュされ、不明であるため、ユーザーには表示されません。

このプロセスは、ユーザーのメールアカウントのセキュリティに完全に依存しています。そのため、達成したいセキュリティのレベルに依存します。これは通常、ほとんどのサイト/アプリで十分です。

27
David Glenn

Troy Huntは、彼の記事でいくつかの優れたポイントを挙げています 安全なパスワードリセット機能の構築について知りたいことはすべて です。最も関連する抜粋は次のとおりです。

[T] 2つの一般的なアプローチがあります。

  1. サーバーで新しいパスワードを生成してメールで送信する
  2. リセットプロセスを容易にする一意のURLを電子メールで送信します

反対の多くのガイダンスにもかかわらず、最初のポイントは本当に私たちがなりたい場所ではありません。これを行う際の問題は、永続的なパスワード(いつでも戻って使用できるパスワード)が安全でないチャネルを介して送信され、受信トレイに存在することを意味することです。

...

しかし、最初のアプローチにはもう1つの大きな問題があります。それは、アカウントの悪意のあるロックアウトを完全に停止させることです。ウェブサイトでアカウントを所有している人のメールアドレスを知っている場合は、パスワードをリセットするだけで、いつでもロックアウトできます。銀の大皿に仕掛けられたサービス拒否攻撃です!これが、リセットがリクエスターの権限を正常に検証した後にのみ発生するリセットである理由です。

リセットURLとは、リセットプロセスのこの特定のインスタンスに固有のWebサイトアドレスのことです。

...

やりたいことは、リセットURLの一部としてメールで送信できる一意のトークンを作成し、ユーザーのアカウントと一緒にサーバー上のレコードに一致させることで、メールアカウントの所有者が本当にパスワード。たとえば、トークンは「3ce7854015cd38c862cb9e14a1ae552b」であり、リセットを実行しているユーザーのIDおよびトークンが生成された時間(詳細は後ほど)とともに表に格納されます。電子メールが送信されると、「Reset /?id = 3ce7854015cd38c862cb9e14a1ae552b」などのURLが含まれ、ユーザーがこれを読み込むと、ページはトークンの存在を確認し、その結果、ユーザーのIDを確認し、パスワードを許可します変更される.

...

リセットURLで行うもう1つのことは、トークンを制限して、リセットプロセスが特定の期間内、たとえば1時間以内に完了するようにすることです。

...

最後に、これが1回限りのプロセスであることを確認します。リセットプロセスが完了したら、トークンを削除して、リセットURLが機能しなくなるようにする必要があります。前のポイントと同様に、これは、攻撃者がリセットURLを悪用できる非常に限られたウィンドウを確保するためです。さらに、リセットプロセスが正常に完了した場合、もちろんトークンは不要になります。

彼は、情報漏えい、CAPTCHA、二要素認証、そしてもちろんパスワードハッシュなどの基本的なベストプラクティスを回避することについて、多くの良い点を挙げています。セキュリティの質問の有用性についてトロイに同意しないことに注意することが重要だと思います。 Bruce Schneierの実践に対する懐疑論

これらすべての質問のポイントは同じです:バックアップパスワード。パスワードを忘れた場合、秘密の質問で身元を確認できるため、別のパスワードを選択したり、現在のパスワードをサイトから電子メールで送信したりできます。カスタマーサービスの観点からは素晴らしいアイデアです。ユーザーは、ランダムなパスワードよりも最初のペットの名前を忘れる可能性は低くなりますが、セキュリティ上ひどいです。秘密の質問への答えは、優れたパスワードよりも推測がはるかに容易であり、情報はより公開されています。

21
Dave Liepmann

私は一緒に行きます:

  1. ユーザーにメールを依頼し、メールが登録されていることを確認します
  2. GUIDを生成し、そのメールに送信します
  3. まだパスワードをリセットしないでください
  4. ユーザーがリンクをクリックしてから、新しいパスを入力する必要があります
  5. ユーザーがサイトにアクセスし、新しいパスを入力した後にリセットボタンをクリックした後にのみ、パスワードをリセットします。
  6. GUIDを短時間で期限切れにすると、より安全になります。
15
andres.santana

電子メールで情報を送信する場合、安全ではありません。誰かがそれを手に入れるにはあまりにも多くの方法があります。あなたの情報を盗もうとする熟練したハッカーにとっては、子供の遊びでしょう。

パスワードや収入情報などの個人情報が電子メールで送信されないようにしてください。そのような情報が漏洩または盗難された場合、あなたやあなたの組織にとって非常に恥ずかしいことになります。セキュリティについて真剣に考えてください。すべてのレンガが倒れるには、その1つのインシデントが必要です。

パスワードの取得については、 パスワードを忘れた場合のベストプラクティスをよくお読みください。

一番下の行は、ベストプラクティスに従うアプリケーションでは、ユーザーが自分のパスワードをリセットできるようにする必要があるということです。個人的なセキュリティの質問を使用する必要があります。アプリケーションは、電子メールを送信したり、パスワードを表示したり、一時的なパスワードを設定したりしないでください。

編集:リンクを更新

11
jinsungy

前述のように、必要なセキュリティのレベルに依存しますが、より高いレベルが必要な場合は、私が見たいくつかの新しいソリューションが含まれます。

  • ユーザーの身元が確認されたとき(セキュリティの質問、メールアドレスなど)に一時パスワードの半分を表示し、残りの半分をメールアカウントに送信します。電子メールアカウントが危険にさらされている場合、同じ人が中間者攻撃を実行する可能性はほとんどありません。 (英国政府ゲートウェイで見られる)

  • 電子メールと別の媒体を介して身元を確認する-たとえば、登録済みのモバイルにテキストで送信されるコード。 (eBay/Paypalで見られます)

DaveGで言及されているように、セキュリティの質問を実装するこれらの2つの極端な間のどこかに行く方法かもしれません。

7
Tom Werner

登録にメールアドレスを含める場合。 「パスワードを忘れた」ボタンは、そのメールアドレスにメールを送信します。情報が信頼できる電子メールに送信されるようにします。

(データベースがハッキングされていない限り、何も安全ではありません)。

6
Toon Krijthe

パスワードのリセットに関する情報を提供する3つの非常に優れたリンクを次に示します。

  1. http://jtauber.com/blog/2006/03/20/account_management_patterns/

  2. (GETを使用してユーザーに確認させないでください): http://www.artima.com/forums/flat.jsp?forum=106&thread=152805&start=15&msRange=15

  3. http://fishbowl.pastiche.org/archives/docs/PasswordRecovery.pdf

お役に立てば幸いです。彼らは確かに私が問題を理解するのを助けました。

5
KingAndrew

アカウント全体で一意のメールアドレスを適用します。

次に、ユーザーがパスワードを変更できる一時ページへのリンクを送信するだけです。 (24時間以内)

このシナリオでは、ユーザーのメールアカウントが最も弱いリンクです。

4
Andrew Harry

ユーザーにパスワードを送信しないでください。自動生成された場合でも。最適なアプローチ(SANSおよびその他のユーザーが推奨および使用):

  1. パスワードを忘れたページで、メール/ユーザーIDとユーザーからの新しいパスワードを尋ねます。
  2. アクティベーションリンクを使用して、そのアカウントに保存されているメールへのリンクをメールします。
  3. ユーザーがそのリンクをクリックすると、新しいパスワードが有効になります。

24時間以内にリンクをクリックしない場合は、リンクを無効にします(パスワードが変更されないようにします)。

ユーザーの同意なしにパスワードを変更しないでください。誰かがパスワードを忘れた場合のリンクをクリックしてアカウント名を見つけたからといって、新しいパスワードを電子メールで送信しないでください。

3
Sucuri