web-dev-qa-db-ja.com

JWTによる認証

私はSPA(React/Redux)を構築しており、ユーザー認証を要求しています。同様のディスカッションは見つかりましたが、以下で概説する質問に対する回答は見つかりませんでした。ここに私が実装することがわかったいくつかのオプションがあります:


オプション1:JWTをlocalStorageに保持する

CSRF攻撃:Cookieが使用されないため、脆弱ではありません。

XSS攻撃:脆弱です。フロントエンドのJSコードは、トークンを盗んで攻撃者に送信できます。 Content-Security-Policyが有効になっていると、攻撃者は自分自身にjwtを盗んだり送信したりすることはできませんが、クライアントブラウザーから直接リクエストを送信できます。


オプション2:CookieにJWTを保持する(secureおよびhttp-only

CSRF攻撃:脆弱です。クライアントは悪意のあるWebサイトをたどることができ、卑劣な要求、Cookieの添付、成功を要求します。

XSS攻撃:脆弱です。 JSはCookieを読み取ることができませんが、JS攻撃者は有効なバックエンドにリクエストを送信するだけで、Cookieが自動的に添付され、すべてのリクエストが成功します。


オプション3:CookieにJWT(xsrf_tokenが設定されている)を保持+ localStorage/JS読み取り可能なCookieにxsrf_tokenを保持

ソリューションは、 this に基づいており、 Double Submit Cookies Method に類似しています。

CSRF攻撃:脆弱ではありません。 xsrf_tokenがcookieと共にクライアントのブラウザから渡されなかったため、クライアントが不正なリクエストを行う悪意のあるWebサイトをフォローしている場合、そのリクエストは破棄されます。また、攻撃者にはCookieが表示されないため(クライアントブラウザから直接来る)、リクエストで添付する偽のxsrf_tokenを作成することはできません。

XSS攻撃:脆弱です。 localStorage/JS読み取り可能なcookieのxsrf_tokenは、攻撃者のJSが読み取ることができます。したがって、攻撃者はクライアントのブラウザから挿入されたJSから直接悪意のあるリクエストを行うことができます。


もともと、オプション1を使用したかったのですが、XSSに関心があったため、代替案を探し始めました。 This 記事と他の多くの人がlocalStorageに対してアドバイスし、 Cookie + CSRF保護。

オプション3は、収集されたデータからの一般的なソリューションのようですが、オプション1と同じようにXSSがまだあります-挿入されたJSは、クライアントブラウザーから直接悪意のある要求を行うことができます。唯一の利点は、オプション1ではJWTエンコードされたデータをユーザー/攻撃者が読み取れることですが、オプション3では読み取れません(Cookieに保存されているため)。 関連質問

Q1。オプション1よりもオプション3の利点は他にありますか?

Q2。オプション3を使用する場合、まだ検討していない他の攻撃方法を導入していますか?

Q3。常にXSSに対して脆弱であるフロントエンド(localStorage/sessionStorage/Reduxストア/ JS読み取り可能なcookie)で状態を保持する代わりに、CSRF緩和策の他の方法はありますか?

セキュリティに特効薬は1つもありません。しかし、おそらくこの問題に対する他のいくつかのアプローチ/オプションがありますか? XSSを削除するには、フルCookieモードにする必要があります。ただし、Cookieのみを使用するには、XSSの脆弱性があるユーザーフロントエンド(localStorage/sessionStorage/Reduxストア/ JS読み取り可能なCookie)にxsrf_tokenが必要です。これは、catch-22の問題のようです。

6
Ilya

簡単な部分から始めましょう:オプション#2は非オプションです。 CSRF保護機能がないため、本質的に脆弱です。実際、オプション#3は、CSRF保護を上にしたオプション#2とほぼ同じです。ですから、#1と#3の間の選択に質問を集中するのは正しいことです。

オプション1よりもオプション3の利点は他にありますか?

あんまり。そして、あなたが言及している利点-Http-OnlyフラグでJWTを保護できること-は、それだけ大きな利点です。

JWTを盗むことは攻撃者にとって便利です。攻撃者は自分のコンピュータからやりたいことを何でもできるからです。しかし、XSSの脆弱性を考えると、JWTを使用して自分のコンピューターで実行できることは何でも、注入されたスクリプトを使用して被害者のコンピューターから行うこともできます。これは攻撃者にとってもう少し煩わしいかもしれませんが、断固とした敵を止めることはできません。

結局のところ、#1と#3の間の選択は、主に個人的な好みの1つだと思います。個人的には1番のほうが好きです。なぜなら、クリーンでわかりやすいからです。さらに、CSRFの状況をきちんと管理します。指を離す必要はありません。

オプション3を使用する場合、まだ検討していない他の攻撃方法を導入していますか?

多分。

一般に、二重送信Cookieパターンの1つの弱点は、 サブドメイン攻撃 を許可することです。これは、JWTを使用することで多少軽減されます。署名されているため、兄弟ドメインはそのCookieを書き換えることができませんでした。しかし、(少なくとも一部のブラウザでは)サブドメインがそれを読み取り、CSRF攻撃を実行する可能性があります。二重送信にフォームフィールドではなくHTTPヘッダーを使用すると、この攻撃は不可能ではないにしても、はるかに困難になります(Flashエクスプロイトのようなものを除く)。

このオプションのセキュリティは、CSRF保護を正しく取得することに完全に依存していることに注意してください。

常にXSSに対して脆弱であるフロントエンド(localStorage/sessionStorage/Reduxストア/ JS読み取り可能なcookie)で状態を保持する代わりに、CSRF緩和策の他の方法はありますか?

いいえ。XSSに対して脆弱である場合、すべてのCSRF保護機能は無効になります。そして、それは本当に重要ではありません。 XSSができれば、CSRFはもう必要ないからです。したがって、XSSの場合にCSRFから保護する方法を考え出そうとすることは、不可能であるだけでなく、無意味でもあります。

XSS攻撃が発生した場合にCSRFトークンを保護する方法について毎分考えるのは、代わりにXSS攻撃を阻止するために費やすべき分です。

3
Anders