私はバックエンドを開発していますREST私のモバイルアプリの1つにAPIを使用しています。永続的なログインを可能にするトークンベースの認証システムを作成したいと思っています。その結果生じるセキュリティ上の欠陥です。
これが私の計画の要約です:
-ユーザーはサーバーに対して資格情報を認証します(注:すべてのパスワードは架空のユーザーテーブルに保存され、ハッシュ+ソルトされます)
-資格情報が正しく検証されていると仮定すると、サーバーはユーザー名、タイムスタンプ、およびランダムなテキスト文字列を連結して作成される認証トークンを生成します。連結はハッシュされます(ハッシュはトークンになります)
-このハッシュはデータベースに保存され、クライアントに送信されます(SSLを使用)。これは、クライアントが行うすべてのリクエストのユーザー名とともにヘッダーに保存されて送信されます。
-その後、トークンとユーザー名がサーバーによって検証され、データベース内のものと一致します。
-注:新しいログインが成功するたびに、新しいトークンが生成されてデータベースに置き換えられ、複数のデバイスがアカウントに一度にログインするのを防ぎます。
すべてのデータベースクエリがパラメーター化されていると仮定すると、このようなシステムを使用することで他にどのような種類の仮想の脆弱性が発生する可能性がありますか?
これは、古典的なセッション管理シナリオです。ただし、複数の角度があります。ワークフローを見ていきましょう。
ユーザーはサーバーへの資格情報を認証します(注:すべてのパスワードは架空のユーザーテーブルに保存され、ハッシュ+ソルトされます)
Argon、bcrypt、PBKDF2などの強力なパスワードハッシュアルゴリズムを使用している場合は、これで問題ありません。
-資格情報が正しく検証されていると仮定すると、サーバーはユーザー名、タイムスタンプ、およびランダムなテキスト文字列を連結して作成される認証トークンを生成します。連結はハッシュされます(ハッシュはトークンになります)
このステップでは、ステートレスセッション管理で最も一般的に使用される自己記述型トークンを作成します。本当にステートレスにしたい場合は、JWTを使用してください。カスタムアルゴリズムを使用する理由はありません。ステートレスになることに注意してください 制限があります (「ログアウト」なし、シングルセッションなし、アイドルタイムアウトなし、真のセッション状態なしなど)
また、ステートレストークンの目的に反するトークンをDBに保存します。こちらからお選びください。単一セッションのセットアップが必要な場合は、 不透明トークンを使用したステートフルなアプローチ を使用します。ステートレスが必要な場合は、サーバー側でステートレスであるという定義そのものに反するため、単一セッションの設定を犠牲にする必要があります。
-このハッシュはデータベースに保存され、クライアントに送信されます(SSLを使用)。これは、クライアントが行うすべてのリクエストのユーザー名とともにヘッダーに保存されて送信されます。
自己記述型トークンを使用すると、完全性が保護されたトークンにすでにあるため、ユーザー名を送信する必要はありません。 (ヒント:JWT)
-その後、トークンとユーザー名がサーバーによって検証され、データベース内のものと一致します。
ステートフルになると、これは単純な検索になります。どのユーザーがこのセッションに属していますか?ステートレスになると、このDBルックアップは排除され、トークンの整合性と有効期限を確認するだけで済みます。
-注:新しいログインが成功するたびに、新しいトークンが生成されてデータベースに置き換えられ、複数のデバイスがアカウントに一度にログインするのを防ぎます。
上記のように、これが必須の場合は、不透明なBearerトークンを使用してステートフルにします。
すべてのデータベースクエリがパラメーター化されていると仮定すると、このようなシステムを使用することで他にどのような種類の仮想の脆弱性が発生する可能性がありますか?
ただし、アプローチに問題はありません。セッションの処理方法(JWTを使用したステートフルまたはステートレス)を決定することをお勧めします。どちらのルートも機能し、トレードオフがあります。ハイブリッドアプローチも機能しますが、それはユースケースによって正当化される必要があり、私が理解していることから、あなたのアプローチはそれに適合しないようです。
それができたら、標準のセキュリティアドバイスに従います。
Web API認証ガイド を確認することもできます。