web-dev-qa-db-ja.com

REST APIでクライアントナンスを使用して再送信とリプレイ攻撃を防ぐ

REST HTTPSがあり(HTTPがブロックされている)APIバックエンドがあり、認証メカニズムとしてJWTを使用しています。クライアント側はiOS/Androidアプリです。重要なAPIに保護層を追加したいクライアントのナンスを使用して、(ほとんど)再送信(ネットワーク/ UIが悪いために意図せずに同じAPIを2回呼び出す)と(おそらく)リプレイ攻撃を防止します。現在の詳細は次のとおりです。

(すべてREST呼び出しはHTTPS経由です)

  1. クライアントはユーザー名とパスワードを使用してAPI呼び出しを行い、サーバー側からJWTと交換します
  2. クライアントは取得したJWT(HTTPヘッダー)を使用して、サーバーにサブシーケンスAPI呼び出しを行います
  3. バックエンドサーバーがJWTを確認してリクエストを実行する

現在の問題は、HTTPパッケージを傍受できるすべてのユーザーがAPI呼び出しを再生できることです。さらに、ネットワークが不良な状況では、クライアントは送信/確認ボタンを2回押してリクエストを再送信する場合があります。

私が提案するのは以下の通りです:

  1. クライアントはユーザー名とパスワードを使用してAPI呼び出しを行い、サーバー側からJWTと交換します
  2. クライアントは、取得したJWTとクライアントが生成したナンスを使用し、バックエンドサーバーへのサブシーケンスAPI呼び出しを行います。
  3. バックエンドサーバーは最初にJWTをチェックし、次にnonceをチェックします。 RedisのようにTTLのk-vストアがあるとします。
  4. NonuceがRedisに存在する場合、リクエストは拒否されます。そうでない場合は、リクエストを受け入れ、nouceをRedisに事前定義済みのTTL(たとえば1時間?))で設定して、リプレイが拒否されるようにします。

私はセキュリティについてほとんど知識がないことを認めざるを得ません。この提案が合法かどうか知りたいのですが?または私は重要な何かを見逃していますか?私のアイデアが問題なければ、ナンスを生成するための最良のアルゴリズムは何ですか?サーバー側では、ナンスがプロトコルに適合するかどうかを確認するために、ナンスを何らかの方法で「デコード」してから、Redisと比較する必要がありますか?

5
mingchuno

クライアント側のnonceには3つの困難があります。

  • クライアントは新しいnonceをいつ生成するかをどのようにして知るのですか? (新しいノンスが生成されるように、どのようなアクションが新しいリクエストを構成しますか?)

  • サーバーはどのようにして有効なナンスを知っていますか?架空の攻撃者が提供した4GBのblobはnonceになれますか?

  • サーバーは、保持するナンスの数と保持期間をどのようにして知るのでしょうか。

サーバーが提供するナンスには2つの利点があります。

  • クライアントが行う必要が少ない
  • サーバーは次に何を期待するかを知っています

サーバーはすべてのナンスの記録を保持する必要はなく、現在のナンスのみを保持します。サーバーは、それを含む最初の有効なリクエストが到着したときに削除できます。新しいnonceは応答で送信できます。

このモデルは、ワンリクエストインフライトの相互作用モデルを適用します。複数の同時リクエストが必要な場合、サーバーはナンスのブロックを生成できますが、課題は、クライアントが一意のリクエストを区別するためのモデルを必要とし、各ユーザーアクションが新しいノンスをプルしないようにすることです。ローカルプール。この問題は、一度に1つのnonceが必要なリクエストのみが実行されるようにアプリを構造化することを提案する必要があります。

6
Jonah Benton

(すべてREST呼び出しはHTTPS経由です)

その後、あなたはすでにリプレイ攻撃から保護されています。

0
ClintM