web-dev-qa-db-ja.com

メールに自動ログインリンクを実装する

PHP Magentoと呼ばれるアプリケーションに取り組んでいます。顧客に電子メールで送信されるリンクを実装し、自動的にログインするようにします =

セキュリティの観点からは非常に重要であることを知っているので、これまでに思いついたのは次のとおりです。

  • 生成されたリンクをデータベーステーブルに保存する
  • 顧客IDに対して保存されたランダムなトークン値を生成する
  • uRLのトークンと顧客IDの両方
  • トークンが顧客IDに保存されているものと一致しない場合は、トークンをリセットします(ブルートフォースを回避するため)
  • リンクを1回だけ使用する
  • リンクに有効期限を設定する

私はPIN codeなどの2番目の要素の使用を避けて、顧客ができる限りシンプルに保つようにしますが、セキュリティが重要であるため、見つけるのが困難です正しいバランス。

Slackには、パスワードを入力したくないときにメールで送信されるマジックリンクがあることは知っています。ここでの考え方は似たようなものになります。

このアプローチに関する推奨事項を探しています。どうすれば改善できますか?私は何を取りこぼしたか ?そのようなアプローチにはどのようなリスクが残され、どのようにそれらを克服するのですか?

8
Raph Petrini

トークンには少なくとも72ビットのエントロピー(9バイト、または12個のBase64文字)が必要です

これは、Secure PSRNG(乱数ジェネレータ)で生成する必要があります。したがって、プログラミング言語の単純なRand()演算子を使用しないでください可能性がある予測可能ですが、PHP内部的に提供する、または/dev/urandomからバイトを読み取る

生成されたリンクをデータベーステーブルに保存する

データベースが部分的に盗まれた場合に備えて、プレーントークンをデータベースに保存しないことをお勧めします。代わりに、トークンのSHA-256ハッシュを保存します。これにより、元のトークンのコピーのみが、お客様に送信した電子メールに含まれます。

パスワードではハッシュも一般的ですが、パスワードのエントロピーは少ないため、通常はBCryptを使用します。トークンには72ビットのエントロピーがあるため、高速なSHAハッシュで十分です。

uRLのトークンと顧客IDの両方

トークンが顧客IDに保存されているものと一致しない場合は、トークンをリセットします(ブルートフォースを回避するため)

これは必要ないと思います。 72ビットのエントロピーでは、トークンをブルートフォースすることはほぼ不可能です。

また、このスキームは、権限のない人物がこの方法でトークンをリセットできることを示唆しています。これは、DOS攻撃の一種です。 (ハッキングではないが、他人がシステムを使用できないようにする)

リンクを1回だけ使用する

残念ながらリンクはブラウザの履歴に保存されるため、これは良い選択です。

リンクに有効期限を設定する

確かに良い考えです。

ただし、最も弱いリンクは、誰かが顧客の電子メールをハッキングする能力であり(通常は複数のデバイス間で同期されます)、これは多くの状況では十分なセキュリティではありませんが、場合によっては許容できることに注意してください。それはあなたの決定です。

このアプローチに関する推奨事項を探しています。どうすれば改善できますか?私は何を取りこぼしたか ?そのようなアプローチにはどのようなリスクが残され、どのようにそれらを克服するのですか?

上記で見逃したことと、このアプローチを全体的に使用することの主なリスクを概説しました。ただし、受信する電子メールの量を制限する必要があることも付け加えておきます。ロボットがパスワードを忘れた場合のフォームに何度も入力して、顧客にスパムを送りたくない場合。

セッション管理と認証自体に関連する他の多くのセキュリティの考慮事項がありますが、それはこの回答の範囲を超えています。

9
Bryan Field