RESTful APIのJWTでステートレス認証を実装しようとしています。
知る限りでは、JWTは基本的にREST呼び出し中にHTTPヘッダーとして渡される暗号化された文字列です。
しかし、リクエストとトークンを盗むを見る盗聴者がいる場合はどうでしょうか?その後、彼は私の身元でリクエストを偽造することができますか?
実際、この懸念はすべてのトークンベースの認証に当てはまります。
それを防ぐ方法は? HTTPSのような安全なチャネルですか?
私は認証をかなり詳細に処理するノードライブラリの作成者です express-stormpath なので、ここでいくつかの情報を説明します。
まず、JWTは通常ではなく暗号化されます。 JWTを暗号化する方法はありますが( JWEs を参照)、これは多くの理由で実際にはあまり一般的ではありません。
次に、任意の形式の認証(JWTを使用するかどうかにかかわらず)は、MitM攻撃(中間者)攻撃の対象となります。これらの攻撃は、インターネット経由でリクエストを行うときに攻撃者がネットワークトラフィックを表示できる場合に発生します。これは、ISPが見ることができるもの、NSAなどです。
これは、SSLが防ぐのに役立つものです:コンピューターからのNETWORKトラフィックを暗号化する->認証時にサーバーを使用することにより、ネットワークトラフィックを監視している第三者は、何らかの方法で可能な限りトークン、パスワードなどを見ることができませんサーバーのプライベートSSLキーのコピーを取得する(可能性は低い)。これが、すべての形式の認証でSSLが必須である理由です。
ただし、誰かがあなたのSSLを悪用してトークンを表示できるとしましょう。あなたの質問に対する答えは、YES、攻撃者はそのトークンを使用してユーザーになりすまし、サーバーにリクエストを行うことができます。
さて、これがプロトコルの出番です。
JWTは、認証トークンの単なる1つの標準です。それらはほとんど何でも使用できます。 JWTが一種のクールな理由は、JWTに追加情報を埋め込むことができ、誰もそれを台無しにしない(署名する)ことを検証できるからです。
ただし、JWT自体は「セキュリティ」とは関係ありません。すべての意図と目的において、JWTは多かれ少なかれAPIキーと同じものです。どこかのサーバーに対する認証に使用するランダムな文字列です。
あなたの質問をより興味深いものにしているのは、使用されているプロトコル(ほとんどの場合OAuth2)です。
OAuth2が機能する方法は、短い期間のみの認証のためにクライアントに(JWTなどの)一時トークンを提供するように設計されていることです!
アイデアは、トークンが盗まれた場合、攻撃者は短期間しか使用できないというものです。
OAuth2では、ユーザー名/パスワードOR APIの資格情報を提供し、引き換えにトークンを取得することにより、サーバーで頻繁に再認証する必要があります。
このプロセスは時々発生するため、トークンは頻繁に変更され、攻撃者が大きなトラブルを起こすことなく、常にあなたになりすますことが「難しく」なります。
これがお役に立てば幸いです^^
私はこれが古い質問であることを知っていますが、私はここに私の0.50ドルを落とすことができると思います、おそらく誰かが私のアプローチを完全に拒否するために改善するか、議論を提供することができます。 HTTPS(ofc)経由のRESTful APIでJWTを使用しています。
これが機能するためには、常に短命のトークンを発行する必要があります(ほとんどの場合、アプリではexp
クレームを30分に、ttl
を3日に設定しているため、このトークンを更新できる限り、 ttl
はまだ有効であり、トークンはブラックリストに登録済みではありません
authentication service
の場合、トークンを無効にするために、メモリ内キャッシュレイヤー(私の場合はredis)をJWT blacklist
/ban-list
として使用したいフロント、いくつかの基準に依存します:(RESTful哲学を破ることは知っていますが、保存されたドキュメントは本当に短命です。残りの存続時間-ttl
クレームをブラックリストに載せています)
注:ブラックリストに登録されたトークンは自動的に更新できません
user.password
またはuser.email
が更新された場合(パスワードの確認が必要)、認証サービスは更新されたトークンを返し、以前のトークンを無効化(ブラックリスト)するため、クライアントがユーザーのIDが何らかの方法で侵害されていることを検出した場合、そのユーザーに変更を求めることができますそのパスワード。ブラックリストを使用したくない場合は、user.updated_at
フィールドに対してiat
(発行元)クレームを検証できます(ただし、jwt.iat < user.updated_at
の場合、JWTは無効です)。最後に、すべての人が行うように、トークンを正常に検証します。
注2:トークン自体(実際には長い)をキャッシュのキーとして使用する代わりに、jti
クレームのUUIDトークンを生成して使用することをお勧めします。これは良いことだと思います(頭に浮かんだのでわかりません)。これと同じUUIDをCSRFトークンとして使用することもできます。これにはsecure
/non-http-only
Cookieを返し、jsを使用してX-XSRF-TOKEN
ヘッダーを適切に実装します。これにより、CSRFチェック用にさらに別のトークンを作成する計算作業を回避できます。
これに少し遅れて申し訳ありませんが、同様の懸念があり、同じものに貢献したいと思っています。
1) rdegges 優れた点を追加しました。JWTが「セキュリティ」とは何の関係もなく、ペイロードを台無しにした(署名)場合、単に検証するだけです。 sslは、侵害の防止に役立ちます。
2)sslも何らかの形で侵害された場合、盗聴者はベアラトークン(JWT)を盗み、本物のユーザーになりすますことができます。次のレベルのステップは、クライアントからのJWTの所有証明」。
3)現在、このアプローチでは、JWTのプレゼンターは特定のProof-Of-Possession(POP)キーを所有しています。受信者はこれを cryptographically 要求が同じ認証ユーザーからのものかどうかを確認できます。
Proof of Possesion の記事を参照し、このアプローチに納得しています。
何か貢献できたら嬉しいです。
乾杯(y)