ログイン中にプレーンテキストのパスワードを送信するための代替手段

Jan 02 2021

注:HTTPS経由でプレーンテキストのパスワードを送信しても大丈夫ですか?およびhttpsセキュリティ-パスワードはサーバー側またはクライアント側のどちらでハッシュする必要がありますか?、ただし、ここでは特定の置換方法について説明します(以下を参照)。


上の新しい認証方法についての記事読んだ後のCloudFlareのブログを、私は見てPOST、「開発者ツール>ネットワーク」で認証中に送信される要求。多くの人気のあるWebサイト(Reddit、HNなど)は、(SSLで保護された)POSTリクエストでパスワードをプレーンテキストで送信します(下のスクリーンショットを参照)。

このログイン方法はまだ業界標準ですか?

次の代替手段は、HTTPS経由でプレーンテキストのパスワードを送信するよりも安全ですか?

  • サインアップ:クライアントはランダムを生成し、リクエストを介しsaltてタプル(username, salt, hash(plain_password + salt))を送信しますPOST。その後、プレーンテキストのパスワードがサーバーに到達することはありません

  • 後続のログイン:サーバーは、指定されたでログインしようとsaltするすべてのクライアントに送り返すusername必要があります。これにより、クライアントは同じソルトでハッシュできます。つまり、これは、サーバーが特定のユーザー名でログインしようとしているユーザーに開示saltしていることを意味します。

  • 利益:サーバーストア(標準で)+塩漬けハッシュされたパスワードだけでなく、サーバは、これまで、一度も平文パスワードを見たことがなかった(サーバーが侵害された場合ので、リスクが限定されています)

ノート:

  • 以来、H = hash(plain_password + salt)今新しいのような少し振る舞いplaintext(の第二の答えを参照?ゼロ知識証明パスワード:なぜクライアント側ではないZKPのパスワードをハッシュされ)、その後、サーバが格納できる(username, salt, server_salt, hash(H + server_salt))データベースで、代わりに(username, salt, H)

  • リプレイ攻撃のリスクを軽減するために、サーバーはnoncesaltログインごとに、1回のログイン試行後に期限切れになる一意のを送信することもできます。

  • ここでの主な目標は、サーバーがプレーンテキストのパスワードまたはその単純なハッシュにアクセスできないようにすることです(サイト全体の単一のレインボーテーブルで逆にすることがよくあります)。攻撃者がユーザーごとに1つのレインボーテーブルを計算しなければならないというリスクは問題ありません。

  • 軽減したい攻撃の例:サーバーがプレーンテキストのパスワードにアクセスでき、侵害された場合(Spectre / Meltdown vulnの例)、ユーザーのプレーンテキストのパスワード(他のWebサイトで再利用される可能性があります)が盗まれてから塩漬けになる可能性があります-ハッシュされてデータベースに保存されます。


回答

14 SteffenUllrich Jan 02 2021 at 14:38

あなたの提案が既存のクライアント側のハッシュアプ​​ローチよりも優れているかどうかはわかりませんが、他の提案よりも実装が複雑だと思います。残念ながら、アクセスしようとしている特定のリスクについては説明していないため、一般的に見られる典型的な脅威を想定しています。

中間者攻撃者

この場合、中間者がトラフィックにアクセスできると想定されます。たとえば、企業ファイアウォールでの信頼できるトラフィックのTLSインターセプトを侵害したか、superfishの場合のように信頼できるCAを取得したためです。

このシナリオでは、攻撃者Hは以前と同じにアクセスできますplain_password。以来H、認証に必要なものすべてがある攻撃者は、このように成功すると、あなたのアプローチは、ここでは、追加の保護を追加しません

弱いパスワードとパスワードの再利用を隠す

クライアント側のハッシュの一般的な議論は、弱いパスワードや再利用されたパスワードをサーバーに公開せず、代わりに複雑な派生パスワードで認証することです。あなたのアプローチは、plain_passwordユーザーがランダムに生成したものをハッシュして、パスワード設定時にサーバーにsalt送信することHでこれsaltを行います。

これは機能しますが、すべての認証には追加の手順が必要になります。最初に、ユーザーに対して以前に使用したソルトをユーザーから取得する必要があります。次に、これを使用してsaltをハッシュできますplain_password。この追加の手順により、最初にサーバーでユーザーを確認する必要があり、後でパスワードを確認できるため、認証がより複雑になります。さらに、これを簡単に実装すると、ユーザーが最初に存在するかどうか(ソルトが返されるかどうか)をさらに認証せずにチェックできるため、情報漏えいが発生します。

この情報漏えいは、ユーザーが存在するかどうかに関係なく、サーバーがソルトを返すことで閉じることができます。もちろん、これは単なるランダムなソルトではありません。そうしないと、攻撃者は同じユーザーを2回チェックし、返されたソルトが異なる場合はユーザーが存在しないと結論付ける可能性があるためです。したがって、ソルトは実際には存在しないユーザーに対して修正する必要があります。つまり、ユーザー名から派生する必要があります。

また、これはアプローチ簡素化するためのパスも示しています。ユーザーがランダムなソルトを生成し、サーバーに保存して後で再度取得する代わりに、クライアント側のユーザー名からソルトを取得するだけで済みます。シンプルは、salt=hash(username+domain)ドメインごとに一意である塩を生成するので、両方にするために十分であろうsaltH異なる場合でも、usernameおよびplain_password異なるドメインに再利用します。そして、あなたのアプローチとは反対に、ユーザーのために以前に使用されたソルトを最初に取得するため、サーバーの追加のトリップは必要ありません


つまり、この単純化されたアプローチは、基本的hash(plain_password+username+domain)に元のパスワードの代わりに送信することです。ドメインは、usernameplain_passwordが複数のサイトで再利用された場合でも、派生したパスワードが再利用されないようにするために追加されます。

8 mti2935 Jan 02 2021 at 21:33

これはまさに、PAKEやSRPなどのプロトコルが解決しようとしている問題です。PAKE / SRPを使用すると、クライアントとサーバーは、クライアントが認識しているパスワード(およびサーバーが認識しているパスワードの派生)に基づいて相互に認証します。

クライアントは、パスワード(またはパスワードに相当するデータ)をサーバーに送信せずに、パスワードを知っていることをサーバーに示します。プロセスの最後に、クライアントとサーバーは共有シークレットを共有します。

サーバーはパスワード(またはパスワードに相当するデータ)を保存せず、辞書攻撃の影響を受けません。有線で送信されたプレーンテキストを表示できる盗聴者または中間者は、パスワードを取得するのに十分な情報を取得できません。これにより、偽の証明書を使用したman-in-the-middle攻撃を効果的に防止し、「フィッシング」サイトがユーザーのパスワードを盗むのを防ぎます。

1passwordがSRPをどのように実装したかについての良い記事については、を参照してください。 https://blog.1password.com/developers-how-we-use-srp-and-you-can-too/

5 mentallurg Jan 02 2021 at 16:00

Steffen Ullrichの答えに加えて:

ログイン中にユーザーがハッシュのみを送信する場合、攻撃者はパスワードを知る必要はありません。パスワードデータベースを盗むだけで十分です。次に、ログイン要求中に、攻撃者はデータベースからハッシュを送信するだけです。サーバーは、クライアントがパスワードを使用してハッシュしたのか、クライアント(攻撃者)が単にハッシュを送信したのかを区別しません。

OPAQUEに関する記事では、この問題にも対処しています。パスワードデータベースを盗むことは、攻撃者の助けにはなりません。プレーンユーザーのパスワードを知っている必要があります。

3 MargaretBloom Jan 03 2021 at 08:43

攻撃者がサーバーを侵害した場合、攻撃者はサーバーで実行されているソフトウェアだけでなく、クライアントで実行されているソフトウェアも制御できます。
美しく設計された認証スキームに関係なく、攻撃者はブラウザに送信される前にそれを変更する可能性があります。
鶏が先か卵が先かという問題が発生しました。攻撃者がパスワードの収集方法とサーバーへの送信方法を制御している場合、パスワードを保護できません。

データ侵害が心配な場合、あなたの方法は保護として機能しますが、適切なパスワードハッシュサーバー側も機能します。

MITM攻撃が心配な場合は、TLSがそれらを解決します。
TLSを介したMITM攻撃について心配している場合は、私が言いたいように、それらに対する適切な防御は常にKravMagaマニュアルから始まります。TLSを破壊するのに十分なリソースを一貫して持っている攻撃者は、適切で特別に訓練されていない個人から必要なものを取得するのに問題はありません(はい、私は拷問、恐喝、誘拐、殺人について話しています)。

サーバーが受信したデータしか読み取れない脅威アクターが心配な場合は、(Steffenによって修正された)アプローチがそれらに対して機能します。ただし、これは奇妙でまれな状況であり、サーバーの構成が大幅に誤っていることや、開発方法が不適切であることがよくあります(つまり、GETリクエストを介して資格情報を送信し、アクセスログを公開して保存します)。これらの間違いに対処するためだけにプロトコルを発明するよりも、これらの間違いを修正する方が簡単です。

あなたが言及した両方の脆弱性(Meltdownは技術的にはSpectreのバリアントであるため、実際には1つだけです)は、最終的にローカル特権の昇格につながり、攻撃者にWebサーバーの完全な制御を与えることに注意してください。攻撃者がWebサーバーによって受信されたデータに読み取り専用でアクセスできるシナリオがどれほどまれであるかを再度強調します。

したがって、多くの大規模なサイトがこれを使用しない理由は、構成の誤りである可能性が最も高い特定の状況でしか追加されないためです。また、攻撃者がサーバーで移行しているデータを読み取ることができれば、ゲームの負け側にいることにも注意してください。念のために言っておきますが、保護を階層化するのは良いことですが、あなたの主な目標は、そもそもそれを実現しないことです。そしてそれに焦点を合わせると、新しいスキームを発明する必要がなくなります。

とにかく、Steffenが示したように、提案されたスキームは、このような奇妙な攻撃モデルで再び機能する可能性があります。私は、辞書に残っている単語である遠隔の可能性を単に支配するのhash(hash(domain + username) + password)ではなく、それでも使用します。mti2935が示したように、SRPはより興味深い代替手段です。証明書ベースの認証(つまり、ブラウザーで処理される認証)は別のオプションです(コメントで提案されているように、汚染されている可能性のあるJSスクリプトで手動で行うよりも優れています)。hash(domain + username + password)domain + username + password