私のプロジェクトでは、「forgot password」機能が必要です。
この種の機能を実装する方法はまだよくわからないので、インターネットで「ベストプラクティス」を見つけたいと思っていましたが、この非常に一般的な機能のすべての重要な側面を扱う便利なものが見つかりませんでした。
これについての私自身の考えはかなり単純です。
ユーザーが自分のパスワードを変更したい場合は、「パスワード変更要求」に添付された一意のトークンuniqueTokenForTheUser
を作成できます。これは、本質的に、バックエンドが要求を送信した正しいユーザーかどうかを識別するための識別子になります。
したがって、たとえば、メールを生成/送信して[email protected]
リンクあり
http://www.example.com/changePassword?token=uniqueTokenForTheUser
uniqueTokenForTheUser
は、一定の間隔でスレッドによってチェックされるテーブルに格納され、ユーザーが実際にパスワードを変更しなかった場合に備えて、トークンの有効期限が切れるとレコードが削除されます。
これは私にはかなり簡単に聞こえますが、「ベストプラクティス」がそこにあるかどうかを再確認したかったのです。その特定のトークンの生成と削除に関しては。
記事やチュートリアルへの提案や参照は大歓迎です!
コメントによって提案された追加リンク:
これだけにHTTPSを使用してから、実装の詳細に進みます。
まず第一に、あなたは ser enumeration から保護したいでしょう。
つまり、ユーザーが存在するかどうかをページで明らかにしないでください。これは電子メール自体でのみ開示されるべきです。
第二に、あなたは リファラー漏れ を避けたいでしょう。ターゲットリンクに外部リンクまたは外部リソースが存在しないことを確認します。これを軽減する1つの方法は、最初のリンクをたどった後にリダイレクトして、トークンがクエリ文字列に含まれないようにすることです。何か問題が発生した場合(データベースが一時的にダウンしている場合など)に標準エラーテンプレートが表示されている場合は、外部参照が含まれていると、トークンが漏洩する可能性があります。
CSPRNGで128ビットのエントロピーを含むトークンを生成します。このサーバー側をSHA-2を使用して保存し、リセットテーブルのデータ漏えいの脆弱性により、攻撃者がパスワードをリセットできるようにします。塩は必要ないことに注意してください。これらのトークンは、しばらくして(たとえば数時間)期限切れにします。
メールリンクでハッシュ化されていないトークンをユーザーに提供するだけでなく、ユーザーが手動でページに移動してからトークン値を貼り付けるオプションを提供します。これにより、クエリ文字列の値がブラウザの履歴に記録されたり、デフォルトでプロキシやサーバーのログに記録されたりするのを防ぐことができます。
オプションで、パスワードのリセットを開始したセッションのセッションIDがリンクをたどったものであることを確認したい場合があります 。これは、攻撃者がユーザーのメールにアクセスできるアカウントを保護するのに役立ちます(たとえば、メールアカウントへのアクセスが制限されたすべてのルールのクイック転送を設定します)。ただし、実際にこれが行うのは、ユーザーがリセットを要求した後に攻撃者が日和見的になるのを防ぐことです。攻撃者が特定のサイトをターゲットにしたい場合、攻撃者は犠牲者に独自のリセットトークンを要求することができます。
パスワードがユーザーの選択のいずれかにリセットされたら、トークンを期限切れにし、ユーザーにメールを送信して、攻撃者が何らかの方法でパスワードをリセットできた場合に備えて、これが発生したことを通知する必要があります(必ずしも制御する必要はありません)。メールアカウントの)-多層防御。 現在のセッションIDをローテーションし、このユーザーアカウントのその他のIDを期限切れにする 。これにより、ユーザーが再度ログインする必要がなくなり、攻撃者によって無効にされたセッションもクリアされます。ただし、一部のユーザーはサイトをログアウトさせて、パスワードが実際にリセットされたことを簡単に確認できるようにします。ログインページにリダイレクトすることで、一部のパスワードマネージャーはログインURLと新しいパスワードを保存することができますが、多くの場合、リセットページから新しいパスワードを検出しています。
また、リセットメカニズムと変更通知について、他の帯域外オプションを検討することもできます。たとえば、SMSまたは携帯電話のアラート。
あなたの考え方は正しい方向に進んでいます。ただし、パスワードを忘れた場合の機能の流れを1つ前に説明することをお勧めします。 誰かが自分のパスワードを忘れたと主張している場合は、この人が本当にパスワードを開始するアカウントの所有者であることを確認する必要があります回復手順。
以下のフローは、ウェブサイトなど、ユーザーが自分でサインアップできるサービスを想定しています(つまり、登録済みのメールやユーザー名のリストは、サインアップ機能を使用して作成できます)。
ステップ1:ユーザーを特定
ステップ2:リカバリ手順を開始
ステップ3:パスワードを更新する
あなたのアプローチでベストプラクティスに近づいています。小さな追加は次のようになります:
ユーザー名をトークンから単に差し引くのではなく、トークンと一致させる必要がある場合があります。
Httpではなくhttpsを使用する必要があります。
他の質問:
生成について:それらを生成する通常の方法はUUIDを使用することですが、コメントが指摘するように、完全にランダムで十分に長い文字列を使用する必要があります。
削除に関して:提案したように、定期的に古い未使用のトークンをクリーンアップできます。たぶん、メールが通常のメールのグレーリストを通過できるような時間枠を使用してください。 15分。
これに関するいくつかの考え:
このトピックの詳細については、 トロイハント をお勧めします。