現在、データベースに保存されている25文字の文字列を生成しています。この文字列は、1回しか使用できず、ユーザー登録後30分で期限切れになります。
http://example.com/security/activate/ZheGgUNUFAbui4QJ48Ubs9Epd
私は簡単なデータベース検索を行い、ロジックは次のとおりです。
アカウントがアクティブ化されておらず、Eメールが検証されておらず、検証コードがまだ有効である場合は、アカウントをアクティブ化し、Eメールアドレスを検証済みとしてマークし、検証コードを使用済みとしてマークします。
たとえば、72時間ごとに、有効期限が切れて使用された検証コードをフラッシュします。これは、クリックしたアクティベーションリンクの有効期限が切れていることをユーザーに知らせるためです。たとえば、ユーザーが翌日にメールを見てリンクを試す場合などです。
ユーザーUUIDをURLに含める必要がありますか?他のものを含める必要がありますか?
アクティベーションリンクが押されたときに、登録フォームのIPアドレスがリクエストのIPアドレスと一致することを確認することを考えましたが、私は主にこの種のものについて私の携帯電話で私のメールを読んでいるため、UXの苦痛になります。
URLに含める25文字の文字列をどのように生成していますか?それは完全にランダムですか、それとも現在の時間に基づいていますか、それともユーザーのメールですか?ランダムで推測できないものにする必要があります。
確認ページが実際にレンダリングされることを確認する必要があります(GETリクエストが発生しただけではありません)。 chrome(およびウイルス対策プログラム)などのブラウザは、プリフェッチとして、またはセキュリティ上の理由からスキャンするために、ユーザーが明示的にクリックせずにURLをロードすることがよくあります。
その結果、悪意のある俳優(イブ)が他の誰かの電子メール(アリス)を使用してアカウントを作成しようとするシナリオが発生する可能性があります。 Eveがサインアップし、Aliceがメールを受け取りました。アリスは、リクエストしていないアカウントに興味があるのでメールを開きます。彼女のブラウザー(またはウイルス対策)がバックグラウンドでURLを要求し、誤ってアカウントをアクティブにします。
ページでJavaScriptを使用して実際にレンダリングされたページを確認し、ユーザーがこのアカウントを作成していないことをユーザーが報告できるリンクをメールに含めます。
大雪の答えに加えて(まだコメントは書けないので)。
フォームを作成し、ユーザーにパスワードを作成するように依頼することは悪くありません。この方法では、ユーザーは新しいパスワードを入力する必要があり、それを送信した後、アカウントがアクティブになります。バックグラウンドのウイルス対策チェックを解決します。
URLはランダムな文字列で十分です。同じコンテンツの2つのキーを一度に取得する可能性はごくわずかです。
一部のISPはIPアドレスをローテーションして、登録したいが登録できない人をブロックする可能性があるため、IPのチェックは適切ではありません。
メールにはリンクではなく、アクティベーションコードを含める必要があります。アカウント管理に使用するリンクをメールで送信しないでください。あなた(正当な当事者)がユーザーへのメールリンク(特にランダムな文字列が長い場合)を送信する場合、正当なメールとフィッシングの試みを区別するのが少し難しくなります。
アクティベーションコードは、簡単にコピーして貼り付けることができ(スペースなし、「+」、「-」など)、手動でも簡単に入力できる文字で構成する必要があります。文字と数字は機能します。アクティベーションコードのセキュリティは、予測不可能であるかどうかに依存します。 CookieのセッションIDと同じように、システムの安全な乱数ジェネレータを使用して値を取得します。
アクティベーションコードはデータベーステーブルに保存する必要があります。各行にはプロファイルID、アクティベーションコードが含まれています。*、および有効期限。プロファイルIDまたは有効期限をCookie、URL、またはアクティベーションコードに含めたくありません。** 悪意のあるユーザーがIDを改ざんして、別のアカウントを乗っ取る可能性があります。セキュリティポリシーがクライアントデータを盲目的に信頼することはできないため、サーバー側でこれらのことを確認する必要があります。
アクティベーションコードは、POSTリクエストを介して送信する必要があります。ユーザーをアカウントアクティベーションURL(https://example.com/security/activate
)残りの登録が完了したとき。アカウントが誤って閉じられた場合に備えて、アカウントのアクティベーションページに簡単にアクセスできるようにします。
GETリクエストでアクションを実行する必要はありません。リンクは、ユーザーの操作なしでアクセスされる可能性があります(ブラウザのプリフェッチまたは電子メールセキュリティサービスのため)。さらに、URLにシークレットを入れると、機密データが漏洩する可能性があります。 (紹介ヘッダーまたはブラウザーのアドオンを通じて)。
IPについては心配しないでください。変更される可能性があります。 (ユーザーエージェントと同じです。)
キャンセル機能が必要かどうかはわかりません。電子メールアドレスに関連付けられた人間が存在するかどうかを判断する方法となる可能性があるため、未承諾の電子メールで登録解除リンクを使用することもありません。アクティベーションコードがブルートフォースに抵抗するのに十分な長さである場合、またはアクティベーションコードの試行回数を制限している場合、アクティベーションコードを最終的に期限切れにするだけでは害はありません。
一方、不要なアカウント有効化メールの数を減らすのは良いことです。アドレスに送信する電子メールの数を制限して、丁寧にすることができます。 1日あたり最大3回、1か月あたり最大5回と言います。 (それが高すぎるか低すぎるかはわかりません。)非ユーザーとして、私はあなたのウェブサイトからのメールを自動的に削除するか、自動的にマークを付けて読むようにします。
不要なアクティベーションメールについて検討する変数はたくさんあります。ほとんどの場合、セキュリティよりもユーザーエクスペリエンスに関係しています。 「アクティベーションをキャンセルし、登録するつもりはないので、このアドレスにメールを送信しない」機能まで提供できますが、これには明らかな問題があります。 (その人のメールアドレスも確認する必要があります。)
*アクティベーションコードをハッシュしても問題ありません。また、パスワードのようにハッシュすることは重要ではありません。各コードには1回限りの使用があり、個人情報が含まれておらず、サーバーによってランダムに生成され、有効期限が切れます。
**暗号化MACを使用して改ざんを実際に防ぐことができますが、ほとんどの開発者にはそれを試みないように強くお勧めします。暗号化を正しく行うのは困難です。
セキュリティプラクティスを使用している場合と同様に、露出と脅威の評価は、固有の環境とユースケースについて評価する必要があるものです。既存の回答は、その評価に十分なタッチポイントを提供するだけでなく、GET
トリガーされたアクションなど、回避すべきことへのポインターを提供します。代わりに、UXの「ユーザー」の部分にさらに焦点を当てます。ページに散らばっているコメントの多くにも触れます。
メールでトリガーされたアクションを使用して「確認」している内容も、考慮すべき要素です。あなたがしているすべてがそれが有効なメールアドレスであることを確認している場合、ほとんどすべてのアクションで十分です。電子メール、アカウントを作成する意図、および電子メールを受信するユーザーがアカウントの作成を開始したユーザーであることを確認するには、もう少し手間がかかります。
ただし、しないでください必要な「努力」は、リマインダーメールの送信です。ユーザーが意図的にアカウントを作成し、有効なメールアドレスを使用し、アカウントを提供する目的でそのアカウントを使用することを想定している場合、ユーザーはメールを探し、可能な限りすぐにアクティベーションプロセスを開始します。リンクやコードなどは、メールを待っている間に他の問題を回避すると、使用前に期限切れになる可能性があります。そのような場合に確認メールを再送信することを許可することは問題ありません。ただし、リマインダーメールは、ユーザーにとってのメリットよりもスパムトリガーである可能性がはるかに高くなります。
ユーザーとして、自分のアカウントをアクティブ化/確認するためのオプションを利用できることを感謝しています。私が遭遇した最も一般的なオプションセットは、メールがクリックまたはカットアンドペーストできるリンクを提供する場所ですand私のページのフォームフィールドに入力できる確認コードウェブサイトのアカウント設定エリア。 5〜9桁の整数以外の確認コードはほとんどありません。
ユーザーとして私に最も信頼できる確認メールは、URLに暗号のようなハッシュが含まれているものです(/verify?l=lgGS2SBjMTU4NjkwNjYxMjI5MDBhZDk2YjEyMzMzYjNhZmQxOb
)を使用すると、自分専用のページが表示され、アカウントの作成に使用したパスワードを入力する必要があります。ハッシュを使用することで、リンクが推測またはブルートフォースではなく電子メールで受信されたことを確認し、電子メールが有効であることを確認します。他のアクションの前にその固有のページを提供することにより、サーバーは、アカウントの作成を確認せずに、送信された電子メールに「有効」のマークを付けることができます。パスワードを入力すると、一部のアンチウイルス、マルウェア検出、またはプリフェッチ操作とは対照的に、反対側に攻撃者がいることが確認されます。パスワードの有効性は、電子メールの受信者とアカウントの作成者が同じ人物であることを、ある程度の確実性で確認します。
提案されている30分の制限時間は少し厳しいように見えますが、脅威評価で24時間の露出が許容できないことが示された場合、24時間は長すぎる可能性があります。ほとんどすべてのユーザーの環境にとって、2時間で十分だと思います。特に、検証を再送信する機能がある場合はそうです。リモートPOPアカウントへの14 kb/s接続のモバイルデバイスを使用しても、120分以内に交換を完了できるはずです。
JSを使用して人間の行動を何らかの形で検証することは問題となる可能性があります。 JSはオフにすることができ、多くのWeb開発者が知りたいと思っているよりもずっと頻繁です。第2に、ブラウザでJSが有効になっている場合でも、広告ブロッカーはサイトごと、またはソースごとにJSをブロックできます。私は、Googleの分析スクリプトを含む多くのJSソースをグローバルにブロックし、Stack Exchangeなどのサイトの一部をホワイトリストに登録します。
メールまたは確認ページにアカウントを「キャンセル」するリンクを含めるのは無駄です。電子メールでは、実際には生産性が低いため、不要なアカウントに関するリンクをクリックすることをお勧めします。代わりに、メールには何もしないとアカウントが確認されず、削除される可能性があることを示す表現が含まれている必要があります。確認ページでキャンセルするリンクは、悪い行動に報いるため、さらに悪いです。古いGoogle snafuの一部として、別のGmailアカウントにメールが頻繁に送られますが、他のアカウントにも逆のことが当てはまると思います。 [昔、Googleはドットで区切られたユーザー名とドットで区切られていないユーザー名をマージしていなかったため、ドットで区切られたユーザー名と他の誰かのドットで区切られていないバージョンは異なるアカウントですが、Googleはときどきスリップし、とにかくメールを受け取ります:()
「確認済み」の電子メールアドレスとアクティベーションリンクをどの程度緊密に結合するかは、ユースケースと脅威の評価の関数です。関連付けられているメールアドレスを変更した後、アカウントを再検証する必要があるときに、少しイライラします。私のプロセスの受け入れ方は、アカウントの「価値」に比例します。私の銀行口座、Paypalなどについては、100%受け入れています。ただし、PcPartsPickerでは、約15%がそのようなプロセスを受け入れます。
IPやユーザーエージェントについては、無視してください。代表的な例として、私はモバイルサイトを使用してサイトを表示し、アカウントを作成することを選択します。私はnotしますが、その上でメールを開きます。アカウントを作成し、何らかの方法で確認または確認する必要があることを知り、メールが提供されている場合、帰宅するまで待ってから、デスクトップでメールを開いて検査できます。したがって、IPとユーザーエージェントは大きく異なります。ただし、私のパスワードは同じままで、元のアカウント作成者としての私を確認するには十分なはずです。
電子メールはタイムズスクエアのジャンボトロンと同じくらい安全であることを覚えておいて、それに従って進んでください。
確認メールに必要なものは、安全で使いやすいものです。
GET
リクエストです。はい、ユーザーはリンクをクリックすることは想定されていませんが、とにかくそれを行います(あなたはそれらを教育するつもりはありません!)。一方、ユーザーエクスペリエンスは、あいまいな文字列をコピーして貼り付ける必要がある場合に比べてはるかに優れています。POST
sする「クリックして確認する」種類のボタンを備えたHTMLフォーム。これにより、URLの投機的な読み込みによって、ユーザーがメールを所有していることを(意図せずに、または悪意を持って)発生させないことが保証されます。住所は知りません。フォームは適切な量の情報を表示して、ユーザーが何が起こっているのかを把握できるようにし、最後のチャンスとして「WTF?」をトリガーする必要があります。ユーザーの場合されなかったそのアカウントを登録します。あなたの質問から、私は以下の仮定をとっていますが、それらのいずれかが無効である場合、私の答えもそうです:
この場合、セキュリティの観点から、あなたのアプローチは絶対に問題ありません。 25文字はランダムな衝突やブルートフォース攻撃に対する十分な保証を提供し、1回の使用でスニッフィングや同様の攻撃から保護し、とにかく誰かが達成できる唯一のことはアカウントをアクティブにすることです。
パフォーマンス上の理由から多数のユーザーがいる場合は、ユーザーIDを含めることをお勧めします(UPDATE:ほんとうに、以下のコメントを参照)文字列トークンでユーザーを見つけると、テーブルスキャンが行われますが、 IDで彼を見つけ、その文字列をフェッチして比較するだけがインデックスルックアップです。ただし、これはユーザーIDを公開するため、ユーザーIDは必要な場合とそうでない場合があります。