web-dev-qa-db-ja.com

パスワードなしの認証(マジックリンクOTPW)システムは安全ですか?

私は自分でパスワードなしの認証システム(ユーザーが自分のメールに送信された「マジックリンク」を使用してログインするだけ)を実装しました。経験のないセキュリティシステムの設計は本当に悪いことだと私は知っているので、自分のシステムに明らかな穴があるかどうかを知りたいと思っています。仕組みは次のとおりです。

  1. ユーザーがメールとJSクライアント(SPA)で一意のユーザー名を入力する
  2. メールとユーザー名がAPIサーバーに送信されます(GET /クエリ文字列)
  3. APIサーバーは、ユーザーデータベース(このDBの設計については以下を参照)を調べて、電子メールが既に存在するかどうかを確認します
  4. そうでない場合、電子メールはユーザー名(新しいユーザー)と共にユーザーデータベースに追加されます。
  5. 一致する場合、APIサーバーはユーザー名がメールと一致することを確認し、一致しない場合はエラーで応答します
  6. APIサーバーは、高エントロピーGUID(長いランダムな文字列)を生成し、それをユーザーデータベースに保存します(電子メールとユーザー名と同じ行にあります)
  7. APIサーバーは、クエリ文字列にGUIDを含むリンクを使用して、特別な '/ auth /'ルートへのメールを送信します
  8. APIサーバーは、このメールが送信された正確な時刻をユーザーデータベースに保存します
  9. その時間から30分以内にリンクが押されなかった場合、GUIDはユーザーデータベースから削除されます(そのため、ユーザーは再度ログインする必要があります)
  10. 時間内にリンクが押された場合、APIサーバーは新しいセッションGUIDを生成し、それをユーザーデータベースに保存し、今後のすべてのリクエストで交換されるCookieに入れます(つまり、新しいリクエストが発生するたびに、APIサーバーはセッション= GUIDは、ユーザーデータベースにあるものと一致し、ログインしていることを示します)
  11. ユーザーがログアウトする場合、セッションGUIDはユーザーデータベースから削除されます
  12. セッションGUIDも3日ごとに削除されます(したがって、ユーザーは3日ごとにログインする必要があります)

ユーザーデータベースには次の列があり、usernameが主キーです。

| username | email | magic_link_guid | magic_link_guid_date | session_guid | session_guid_date |

修正方法がわからない問題:

  1. リクエストごとにデータベース呼び出しが行われますが、これは適切ではありません
  2. この方法では、ユーザーロールの処理は非常に困難になります。
  3. これはXSS/CRSF攻撃の影響を受けやすいようです

繰り返しますが、自分のシステムをロールアウトすることは悪いことですが、.NET/C#:(。

4
user133747

あなたが説明するのは、トークン認証システムです。 Isはそれほど悪くはありません。コメントで述べられているように、パスワードを忘れた機能を実装する一般的な方法です。

redmine などのよく知られたアプリケーションは、APIを使用した自動操作の実装をスムーズにするために、このような認証システムをネイティブで提供しています。

1つの問題は、セッションGUIDと呼ばれるトークンの期間です。ここでは、ユーザーに少なくとも3日ごとに接続を強制します。職業上の理由である場合、従業員は通常、3日間を超える休暇を取ることが許可されており、非専門の仕事では3日ごとに休暇をとることがenthusiam( 30日連続でサイトにアクセスするためのSEネットワークのシルバーバッジから)。ユーザーはネットワークにアクセスせずに山のトラックに行きますか?つまり、ユーザー名と電子メールのみに依存するパスワード生成を集中的に使用する必要があり、一般的な使用には安全ではありません。しかし、セッションGUIDが長く使用されるほど、盗まれるリスクが高くなることも知っています。

もう1つの弱点は、トークンを格納する永続的なCookieクライアント側の処理です。それは多かれ少なかれ、クライアント上でパスワードをクリアテキストで保存することであり、これは悪いことがわかっています。これだけでも、セキュリティを意識したユーザーを怖がらせるはずです。たとえばredmineでは、トークンが生成されてアプリに保存され、ユーザーがAPIリクエストに使用する直前にトークンが生成されます。

今あなたの質問のために:

  • リクエストごとにデータベース呼び出しが行われますが、これは適切ではありません

    ここで問題ありません。キャッシュはその問題を軽減するためのものです。手作業で行うことはせず、よく知られているキャッシュに依存してください。また、ブラウザクライアント側について言えば、ユーザーが認証されると、HTTP(またはHTTPS)セッションに依存できます。

  • この方法では、ユーザーロールの処理は非常に困難になります。

    ユーザーの役割はクライアント側では処理されません。ユーザーに許可されているロールを説明するテーブルが必要です:User_ID | Role_ID。ユーザーを見つけたら、そのロールを検索し、サーバー側にセッションに保存します。または、接続されていないAPIを使用する場合は、キャッシュに依存します。

  • これはXSS/CRSF攻撃の影響を受けやすいようです

    それは問題かもしれないし、そうでないかもしれません。ただし、少なくともトークンCookieが自分のドメインにのみ関連付けられていることを確認する必要があります。また、フォーム上の一般的な緩和方法に依存します。

TL/DR:これはトークン認証システムです。メイン認証システムの補完として使用できますが、単独で使用すると、説明した実装に重大な弱点があります。反対に、残りの質問は実際には問題ではなく、一般的な方法で回答できます。

2
Serge Ballesta