フォームベースのWebサイト認証の決定的なガイド[終了]


5372

Webサイトのフォームベースの認証

スタックオーバーフローは、非常に具体的な技術的な質問だけでなく、一般的な問題のバリエーションを解決する方法に関する一般的なガイドラインにも役立つはずです。「Webサイトのフォームベースの認証」は、このような実験に適したトピックです。

次のようなトピックを含める必要があります。

  • ログイン方法
  • ログアウトする方法
  • ログインしたままにする方法
  • Cookieの管理(推奨設定を含む)
  • SSL / HTTPS暗号化
  • パスワードを保存する方法
  • 秘密の質問を使う
  • 忘れられたユーザー名/パスワード機能
  • noncesを使用したクロスサイトリクエストフォージェリ(CSRF)の防止
  • OpenID
  • 「記憶」チェックボックス
  • ユーザー名とパスワードのブラウザ自動補完
  • シークレットURL(ダイジェストで保護されたパブリックURL
  • パスワードの強度を確認する
  • 電子メールの検証
  • そして、はるかに関する ベースの認証を構成します ...

次のようなものは含めないでください。

  • 役割と承認
  • HTTP基本認証

私たちを助けてください:

  1. サブトピックの提案
  2. このテーマに関する良い記事を提出する
  3. 公式回答を編集する

52
HTTP基本認証を除外する理由 Ajax経由でHTMLフォームで機能します:peej.co.uk/articles/http-auth-with-html-forms.html
システムの一時停止

55
HTTP Basic Authには、ブラウザを忘れることが(比較的)難しいという性質があります。また、接続(つまりHTTPS)を保護するためにSSLを使用しない場合、それは恐ろしく安全ではありません。
ドナルフェロー2010年

24
セッション(固定とハイジャックを含む)Cookie(安全でhttpのみのフラグ)のHTTPベースのSSO
symcbean

29
HttpOnlyJavaScriptベースのCookieの盗難(XSS攻撃のサブセット)を防ぐ非常に便利なCookieフラグについても、どこかで言及する必要があります。
アランH.

80
ワオ。長い回答、それらのいくつかに対する数十の賛成投票ですが、HTTP経由でログインフォームを提供する際の一般的な間違いについては誰も言及していません。「しかし、https:// ...に送信する」と言って、フォームが提供された暗号化されていないページを攻撃者が書き換えていないかどうかを尋ねたとき、空白の視線しか得られなかった人とさえ議論しました。
dzuelke

回答:


3764

パートI:ログイン方法

認証のためにサーバー側のスクリプトに値をPOSTするlogin + password HTMLフォームを作成する方法をすでに知っていると想定します。以下のセクションでは、適切な認証のパターンと、最も一般的なセキュリティの落とし穴を回避する方法について説明します。

HTTPSを使用するか、またはHTTPSを使用しないか?

接続がすでに安全である(つまり、SSL / TLSを使用してHTTPS経由でトンネルされる)場合を除き、ログインフォームの値はクリアテキストで送信されます。これにより、ブラウザとWebサーバーの間の回線を盗聴しているすべてのユーザーが、ログインが通過したときにログインを読み取ることができます。使って。このタイプの盗聴は政府によって日常的に行われていますが、一般的に、私たちはこれを言う以外に「所有された」ワイヤーに対処しません:HTTPSを使用してください。

本質的に、ログイン中の盗聴/パケットスニッフィングから保護する唯一の実用的な方法は、HTTPSまたは別の証明書ベースの暗号化スキーム(TLSなど)または実証済みでテスト済みのチャレンジ/レスポンススキーム(Diffie-Hellmanなど)を使用することですベースのSRP)。その他の方法は、盗聴者によって簡単に回避できます

もちろん、少し実用的でない場合は、何らかの2要素認証方式(Google認証システムアプリ、物理的な「冷戦スタイル」コードブック、RSAキージェネレータドングルなど)を使用することもできます。正しく適用されれば、これは保護されていない接続でも機能する可能性がありますが、開発者が2要素認証を実装してもSSLを実装しないとは想像しがたいです。

(しないでください)Roll-your-own JavaScript暗号化/ハッシュ

WebサイトにSSL証明書を設定することの知覚された(現在は回避可能ですが)コストと技術的な難しさを考えると、一部の開発者は、セキュリティで保護されていないワイヤを介してクリアテキストのログインを渡さないようにするために、ブラウザ内のハッシュまたは暗号化スキームを独自に導入したいと考えています。

これは高貴な考えですが、上記のいずれかと組み合わせない限り、つまり、強力な暗号化で回線をセキュリティで保護するか、実証済みのチャレンジ/レスポンスを使用しない限り、本質的に役に立たない(そしてセキュリティ上の欠陥になる可能性があります)メカニズム(それが何であるかがわからない場合は、それが証明するのが最も難しく、設計するのが最も難しく、デジタルセキュリティの概念を実装するのが最も難しいことの1つだと知ってください)。

パスワードのハッシュはパスワードの漏洩に対して効果的である可能があることは事実です、リプレイ攻撃、中間者攻撃/ハイジャックに対して脆弱です(攻撃者がセキュリティで保護されていないHTMLページに数バイトを挿入してから、ブラウザでは、JavaScriptのハッシュをコメントアウトするか、ブルートフォース攻撃を行うことができます(ユーザー名、salt、ハッシュされたパスワードの両方を攻撃者に渡しているため)。

人道に対するキャプチャ

CAPTCHAは、特定のカテゴリの攻撃を阻止するためのものです。自動化された辞書/ブルートフォースの試行錯誤で、人間のオペレーターがいません。これが本当の脅威であることは間違いありませんが、CAPTCHAを必要としないシームレスに対処する方法があり、特に適切に設計されたサーバー側ログインスロットリングスキームがあります。これらについては後で説明します。

CAPTCHA実装は同じように作成されていないことを知ってください。それらは人間が解決できない場合が多く、そのほとんどは実際にはボットに対して効果がなく、安価な第三世界の労働力に対しては効果がありません(OWASPによると、現在のスウェットショップのレートは500テストあたり12ドルです)。一部の国では技術的に違法です(OWASP認証チートシートを参照)。CAPTCHAを使用する必要がある場合は、GoogleのreCAPTCHAを使用してください。これは、定義によりOCRが難しいため(すでにOCRと誤って分類されたブックスキャンを使用しているため)、ユーザーフレンドリーになるように非常に努力しています。

個人的には、CAPTCHASは煩わしいと感じる傾向があり、ユーザーが何度もログインに失敗し、スロットルの遅延が最大になったときの最後の手段としてのみ使用します。これが許容できるほどまれに発生し、システム全体を強化します。

パスワードの保存/ログインの確認

これは、近年見られたすべての非常に公表されたハッキン​​グとユーザーデータリークの後、ようやく一般的な知識になるかもしれませんが、それは言う必要があります:データベースにクリアテキストでパスワードを保存しないでください。ユーザーデータベースは、SQLインジェクションを通じて定期的にハッキング、リーク、収集されます。未加工のプレーンテキストのパスワードを保存している場合は、ログインセキュリティのためのインスタントゲームオーバーです。

パスワードを保存できない場合、ログインフォームからPOSTされたログインとパスワードの組み合わせが正しいことをどのように確認しますか?答えは、キー導出関数を使用したハッシュです。新しいユーザーが作成されるか、パスワードが変更されるたびに、パスワードを取得し、それをArgon2、bcrypt、scrypt、PBKDF2などのKDFで実行し、クリアテキストのパスワード( "correcthorsebatterystaple")を長いランダムに見える文字列に変換します。 、データベースに保存する方がはるかに安全です。ログインを確認するには、入力したパスワードに対して同じハッシュ関数を実行します。今回はソルトを渡して、結果のハッシュ文字列をデータベースに保存されている値と比較します。Argon2、bcrypt、およびscryptはソルトをハッシュとともに保存しています。詳細については、sec.stackexchangeに関するこの記事をご覧ください。

ソルトが使用される理由は、ハッシュ自体では不十分であるためです。レインボーテーブルからハッシュを保護するために、いわゆる「ソルト」を追加する必要があります。ソルトは、完全に一致する2つのパスワードが同じハッシュ値として保存されることを効果的に防ぎ、攻撃者がパスワード推測攻撃を実行している場合、データベース全体が1回の実行でスキャンされるのを防ぎます。

ユーザーが選択したパスワードは十分に強力ではないため(通常、十分なエントロピーが含まれていないため)、暗号化ハッシュをパスワードの保存に使用しないでください。また、ハッシュにアクセスできる攻撃者がパスワード推測攻撃を比較的短時間で完了する可能性があります。これがKDFが使用される理由です。これらは効果的に「キーをストレッチ」します。つまり、攻撃者が作成するすべてのパスワードでハッシュアルゴリズムが複数回繰り返され、たとえば10,000回繰り返されるため、攻撃者はパスワードを10,000倍遅く推測します。

セッションデータ-「Spiderman69としてログインしています」

サーバーがユーザーデータベースに対してログインとパスワードを検証し、一致するものが見つかったら、システムはブラウザが認証されたことを記憶する方法を必要とします。この事実は、サーバー側でのみセッションデータに格納する必要があります。

セッションデータに慣れていない場合は、次のように機能します。ランダムに生成された単一の文字列が期限切れになるCookieに格納され、サーバーに格納されているデータのコレクション(セッションデータ)を参照するために使用されます。MVCフレームワークを使用している場合、これは間違いなくすでに処理されています。

可能であれば、ブラウザに送信するときに、セッションCookieにセキュアフラグとHTTP Onlyフラグが設定されていることを確認してください。HttpOnlyフラグは、XSS攻撃を通じて読み取られるCookieに対するある程度の保護を提供します。セキュアフラグは、CookieがHTTPS経由でのみ送信されることを保証し、ネットワークスニッフィング攻撃から保護します。Cookieの値は予測できません。存在しないセッションを参照するCookieが提示された場合、その値をすぐに置き換えて、セッションが固定されないようにする必要があります。

パートII:ログインを維持する方法-悪名高い「Remember Me」チェックボックス

永続的なログインCookie(「remember me」機能)は危険ゾーンです。一方では、ユーザーがそれらの処理方法を理解していれば、従来のログインと同じくらい完全に安全です。そして、その一方で、それらは公共のコンピューターでそれらを使用してログアウトするのを忘れ、ブラウザーのCookieとは何か、またはそれらを削除する方法を知らない不注意なユーザーの手に渡る巨大なセキュリティリスクです。

個人的には、定期的にアクセスするWebサイトの永続的なログインが好きですが、それらを安全に処理する方法を知っています。ユーザーが同じことを知っていると確信している場合は、クリーンな良心で永続的なログインを使用できます。そうでない場合、まあ、あなたは、ログイン資格情報に不注意なユーザーがハッキングされた場合にそれを持ち込んだという哲学に同意するかもしれません。私たちがユーザーの家に行って、それらのモニターの端に並んだパスワードを使って、フェイスパームを誘発するポストイットのメモをすべて剥ぎ取るようなものでもありません。

もちろん、いくつかのシステムが持っている余裕はありません任意のアカウントがハッキング。このようなシステムでは、永続的なログインを正当化する方法はありません。

永続的なログインCookieを実装する場合は、次のようにします。

  1. 最初に、このテーマに関するParagon Initiativeの記事を読んでください。たくさんの要素を正しく取得する必要があります。この記事では、それぞれの要素をうまく説明しています。

  2. そして、最も一般的な落とし穴の1つを繰り返すために、永続的なログインクッキー(トークン)をデータベースに保存しないでください。ログイントークンは同等のパスワードであるため、攻撃者がデータベースを手に入れれば、平文のログインパスワードの組み合わせであるかのように、トークンを使用して任意のアカウントにログインできます。したがって、永続的なログイントークンを格納する場合は、ハッシュを使用しますhttps://security.stackexchange.com/a/63438/5002によると、この目的には弱いハッシュで十分です)。

パートIII:秘密の質問の使用

「秘密の質問」を実装しないでください。「秘密の質問」機能は、セキュリティ対策パターンです。必読リストのリンク4の論文を読んでください。あなたは彼女のYahoo!の後にサラPalinにそれについて尋ねることができます。以前の大統領選挙でメールアカウントがハッキングされたのは、彼女のセキュリティの質問に対する答えが「ワシラ高校」だったからです!

ユーザー指定の質問であっても、ほとんどのユーザーは次のいずれかを選択する可能性が高いです。

  • 母親の旧姓や好きなペットのような「標準的な」秘密の質問

  • ブログ、LinkedInのプロフィールなどから誰でも持ち上げられる簡単な雑学

  • パスワードを推測するよりも答えやすい質問。適切なパスワードについては、これは想像できるすべての質問です

結論として、セキュリティの質問は本質的にすべての形式とバリエーションで本質的に安全ではなく、何らかの理由で認証スキームで使用されるべきではありません。

セキュリティの質問が実際に存在する本当の理由は、メールにアクセスして再アクティベーションコードにアクセスできないユーザーからのサポートコールの費用を節約できることです。これは、セキュリティとサラペイリンの評判を犠牲にして行われます。価値がある?おそらく違います。

パートIV:パスワードを忘れた場合の機能

忘れた/紛失したユーザーパスワードの処理にセキュリティの質問使用してはならない理由についてはすでに述べました。言うまでもなく、ユーザーに実際のパスワードを電子メールで送信してはなりません。この分野では、少なくとも2つの、あまりにも一般的な回避すべき落とし穴があります。

  1. 忘れたパスワードを自動生成された強力なパスワードにリセットしないでください。このようなパスワードは覚えがたいことで有名です。つまり、ユーザーはパスワードを変更するか書き留める必要があります。たとえば、モニターの端にある明るい黄色のポストイットに書き留める必要があります。新しいパスワードを設定する代わりに、ユーザーがすぐに新しいパスワードを選択できるようにします-これはとにかくやりたいことです。(これの例外は、ユーザーがパスワードマネージャーを使用してパスワードを保存/管理するために普遍的に使用している場合で、パスワードを書き留めておかないと覚えることは通常不可能です)。

  2. 失われたパスワードコード/トークンは、常にデータベースにハッシュします。AGAIN攻撃者がデータベースに手を得た場合にはハッシュ化されなければならないので、このコードは、等価パスワードの別の例です。紛失したパスワードコードがリクエストされた場合は、プレーンテキストコードをユーザーのメールアドレスに送信し、ハッシュしてデータベースに保存します。元のコードは破棄してください。パスワードや永続的なログイントークンと同じです。

最後の注意:「紛失したパスワードコード」を入力するためのインターフェースが、ログインフォーム自体と少なくとも同じくらい安全であることを常に確認してください。非常に長い「失われたパスワードコード」(たとえば、大文字と小文字が区別される16文字の英数字)を生成することをお勧めしますが、ログインフォーム自体と同じスロットルスキームを追加することを検討してください。

パートV:パスワードの強度の確認

最初に、現実をチェックするためにこの小さな記事を読みたくなるでしょう:最も一般的な500のパスワード

わかりましたので、多分リストではありません正規の上の最も一般的なパスワードのリストの任意のシステムのどこか今まで、それは何の強制ポリシーが所定の位置に存在しないとき、人々が自分のパスワードを選択する方法が不十分の良い兆候です。さらに、最近盗まれたパスワードの公開されている分析と比較すると、リストは恐ろしく自宅に近いように見えます。

したがって、パスワードの強度に関する最低要件はなく、2%のユーザーが上位20の最も一般的なパスワードの1つを使用しています。意味:攻撃者が20回だけ試行した場合、Webサイトの50アカウントに1アカウントがクラッキング可能になります。

これを阻止するには、パスワードのエントロピーを計算してから、しきい値を適用する必要があります。国立標準技術研究所(NIST)の特別刊行物800-63には、非常に優れた提案がいくつかあります。つまり、辞書とキーボードレイアウト分析(たとえば、「qwertyuiop」は不適切なパスワードです)と組み合わせると、18ビットのエントロピーレベルで、不適切に選択されたすべてのパスワードの99%を拒否できます。パスワードの強度を計算し、ユーザーに視覚的な強度メーターを表示するだけで十分ですが、不十分です。強制されない限り、多くのユーザーはそれを無視するでしょう。

また、エントロピーの高いパスワードを使いやすくするために、Randall MunroeのPassword Strength xkcdを強くお勧めします。

Troy HuntのHave I Below Pwned APIを利用して、ユーザーのパスワードを、公開データ侵害で侵害されたパスワードと照合します。

パートVI:はるかに-または:即時起動ログイン試行の防止

最初に、数字を見てください:パスワード回復速度-パスワードはどれくらいの期間有効ですか

そのリンクのテーブルを確認する時間がない場合は、それらのリストを次に示します。

  1. そろばんを使ってクラックしても、弱いパスワードをクラックするのにほとんど時間はかかりません

  2. 大文字と小文字を区別しない場合、英数字の9文字のパスワードをクラックするのに実質的に時間はかかりませ

  3. 8文字未満の複雑な記号と文字と数字の大文字と小文字のパスワードを解読するのに実質的に時間はかかりません(デスクトップPCは、最大7文字のキースペース全体を検索できます)日または時間の)

  4. ただし、1秒あたりの試行回数が1回に制限されている場合、6文字のパスワードを解読するのにも非常に時間がかかります

では、これらの数字から何を学ぶことができるでしょうか?ええ、たくさんありますが、最も重要な部分に焦点を当てることができます。大量の高速な連続ログイン試行(つまり、ブルートフォース攻撃)を防止することは、実際にはそれほど難しくありません。しかし、それを正しく防止することは、思ったほど簡単ではありません。

一般的に、ブルートフォース攻撃(および辞書攻撃)に対して効果的な3つの選択肢がありますが、既に強力なパスワードポリシーを採用しているため、問題にはなりません

  • N回の試行が失敗した後、CAPTCHAを提示します(地獄のように迷惑で、多くの場合無効ですが、ここでは繰り返します)。

  • N回の試行の失敗後にアカウントロックし、電子メールの検証を要求する(これは、発生するのを待っているDoS攻撃です)

  • そして最後に、ログインスロットリング:つまり、N回の試行が失敗した後の試行間の時間遅延を設定します(そうです、DoS攻撃はまだ可能ですが、少なくとも攻撃の可能性ははるかに低く、引き離すのははるかに複雑です)。

ベストプラクティス#1:次のように、失敗した試行の数とともに増加する短い遅延時間。

  • 1回失敗した=遅延なし
  • 2回失敗した場合= 2秒の遅延
  • 3回失敗した= 4秒の遅延
  • 4回失敗した場合= 8秒の遅延
  • 5回失敗した場合= 16秒の遅延

結果として生じるロックアウト時間は、以前のロックアウト時間の合計よりもわずかに長いため、このスキームを攻撃するDoSは非常に非実用的です。

明確にするために:遅延は、ブラウザーに応答を返す前の遅延ではありません。これは、特定のアカウントまたは特定のIPアドレスからのログイン試行がまったく受け入れられないか評価されないタイムアウトまたは不応期に似ています。つまり、ログインが成功しても正しい認証情報が返されず、誤った認証情報によって遅延の増加が引き起こされることはありません。

ベストプラクティス#2: N回の試行が失敗した後に有効になる中程度の時間遅延。

  • 1〜4回失敗した場合=遅延なし
  • 5回失敗した場合= 15〜30分の遅延

このスキームを攻撃するDoSは実際的ではありませんが、実行可能です。また、このような長い遅延は、正当なユーザーにとっては非常に煩わしいものであることに注意してください。忘れっぽいユーザーはあなたを嫌います。

ベストプラクティス#3: 2つのアプローチを組み合わせる-次のように、N回の試行が失敗した後に有効になる固定の短い遅延。

  • 1〜4回失敗した場合=遅延なし
  • 5回以上失敗した場合= 20秒の遅延

または、次のように上限が固定された遅延の増加。

  • 1回失敗した場合= 5秒の遅延
  • 2回失敗した= 15秒の遅延
  • 3回以上の失敗= 45秒の遅延

この最終的なスキームは、OWASPのベストプラクティスの提案(MUST-READリストのリンク1)から取られたものであり、たとえそれが明らかに制限的な側面にあるとしても、ベストプラクティスと見なされるべきです。

しかし、経験則として、私は言うでしょう:パスワードポリシーが強力であるほど、遅延によるユーザーのバグを減らす必要があります。強力な(大文字と小文字を区別する英数字+必要な数字と記号)9文字以上のパスワードが必要な場合は、スロットリングをアクティブにする前に、ユーザーに遅延のないパスワードを2〜4回試行させることができます。

この最終ログインスロットルスキームを攻撃するDoSは、非常に非現実的です。そして最後の仕上げとして、永続的な(Cookie)ログイン(および/またはCAPTCHAで検証されたログインフォーム)の通過を常に許可するので、正当なユーザーが攻撃の進行中に遅れることもありません。このように、非常に非現実的なDoS攻撃は、非常に非現実的な攻撃になります。

さらに、管理アカウントは最も魅力的なエントリポイントであるため、管理アカウントでより積極的な調整を行うことは理にかなっています。

パートVII:分散ブルートフォース攻撃

余談ですが、より高度な攻撃者は、「アクティビティを分散させる」ことでログインスロットリングを回避しようとします。

  • ボットネットでの試行を分散してIPアドレスのフラグ付けを防止する

  • 1人のユーザーを選んで50.000の最も一般的なパスワード(スロットルのためにできない)を試すのではなく、最も一般的なパスワードを選んで50.000人のユーザーに対して試行します。そうすることで、CAPTCHAやログインスロットリングなどの最大試行回数を回避できるだけでなく、最も一般的な1番目のパスワードが49.995よりもはるかに可能性が高いため、成功の可能性も高くなります。

  • 各ユーザーアカウントのログインリクエストを30秒間隔で間隔をあけてレーダーの下に忍び込む

ここでのベストプラクティスは、失敗したログインの数をシステム全体ログに記録し、サイトの不正ログイン頻度の移動平均を、すべてのユーザーに課す上限の基準として使用することです。

抽象的すぎる?言い換えましょう:

サイトで過去3か月間、1日あたり平均120回の不正ログインがあったとします。これを使用して(移動平均)、システムはグローバル制限をその3倍に設定する可能性があります。24時間で360回失敗しました。次に、すべてのアカウントで失敗した試行の合計数が1日以内にその数を超えた場合(さらに良い場合は、加速率を監視し、計算されたしきい値でトリガーします)、システム全体のログインスロットルをアクティブにします。つまり、すべてのユーザーに短い遅延が発生します(ただし、Cookieログインおよび/またはバックアップCAPTCHAログインを除く)。

私はまた、詳細と質問を投稿し、分散型ブルートフォース攻撃をかわす際トリッキーなピットフォールを回避する方法について非常に良い議論をしました

パートVIII:2要素認証および認証プロバイダー

悪用、パスワードの書き留めと紛失、鍵が盗まれたラップトップ、またはユーザーがフィッシングサイトにログインを入力することによって、認証情報が侵害される可能性があります。ログインは、2要素認証でさらに保護できます。これは、電話、SMSメッセージ、アプリ、ドングルから受信した使い捨てコードなどの帯域外要素を使用します。複数のプロバイダーが2要素認証サービスを提供しています。

認証は、シングルサインオンサービスに完全に委任できます。シングルサインオンサービスでは、別のプロバイダーが資格情報の収集を処理します。これにより、信頼できるサードパーティに問題が発生します。GoogleとTwitterはどちらも標準ベースのSSOサービスを提供していますが、Facebookは同様の独自のソリューションを提供しています。

ウェブ認証についての必読リンク

  1. OWASP認証ガイド / OWASP認証チートシート
  2. Webでのクライアント認証の推奨事項と禁止事項(非常に読みやすいMITリサーチペーパー)
  3. ウィキペディア:HTTP cookie
  4. フォールバック認証のための個人的な知識の質問:Facebookの時代のセキュリティに関する質問(非常に読みやすいバークレーの研究論文)

67
まあ、私はキャプチャの部分に本当に同意しません、はい、キャプチャは迷惑であり、壊れることがあります(recaptchaを除くが、これは人間にはほとんど解決できません!)しかし、これはスパムフィルターを使用しないと言っているのとまったく同じです0.1%未満の偽陰性..このサイトはキャプチャを使用しています。完璧ではありませんが、大量のスパムを削減し、それに代わるものはありません
Waleed Eissa 2009

235
@ジェフ:私の返信に問題があるとのこと、ごめんなさい。この回答についてメタについての議論があることを知りませんでした。もし私に頼まれたら喜んでそれを編集したでしょう。そして、私の投稿を削除すると、私のアカウントから1200の評判が削除されました。これは、(:
Jens Roland

13
「認証トークンを送信した後、システムはあなたが認証されたことを記憶する方法を必要とします-この事実は常にサーバー側にセッションデータに保存されるべきです。セッションデータを参照するためにCookieを使用できます。」結構です。暗号で署名されたCookieを使用できます(ステートレスサーバーの場合は!)。それは偽造することは不可能であり、サーバーのリソースを拘束せず、スティッキーセッションや他の悪意のあるものを必要としません。
Martin Probst、2011

12
「デスクトップPCは90日未満で最大7文字のフルキースペースを検索できます」最近のGPUを搭載したマシンは、7文字のキースペース全体を1日未満で検索できます。最上位のGPUは、1秒あたり10億のハッシュを管理できます。 golubev.com/hashgpu.htm これは、直接対処されていないパスワードの保存に関するいくつかの結論につながります。
フランクファーマー

9
私は驚いCSRF保護が...言及されていないんだ
Flukey

418

決定的な記事

資格情報の送信

資格情報を100%安全に送信する唯一の実用的な方法は、SSLを使用することです。JavaScriptを使用してパスワードをハッシュすることは安全ではありません。クライアント側のパスワードハッシュの一般的な落とし穴:

  • クライアントとサーバー間の接続が暗号化されていない場合、実行するすべての処理が中間者攻撃に対して脆弱になります。攻撃者は、受信したJavaScriptを置き換えてハッシュを壊したり、すべての資格情報をサーバーに送信したり、クライアントの応答を聞いたり、ユーザーを完全に偽装したりすることができます。
  • サーバーで追加の冗長な作業を行わないと、サーバーが受信したハッシュ化されたパスワードの安全性低下します。

SRPと呼ばれる別の安全な方法がありますが、それは特許を取得しており(無料でライセンスされていますが)、優れた実装はほとんどありません。

パスワードの保存

パスワードをプレーンテキストとしてデータベースに保存しないでください。自分のサイトのセキュリティを気にしなくても。一部のユーザーがオンライン銀行口座のパスワードを再利用するとします。したがって、ハッシュ化されたパスワードを保存し、元のパスワードは捨ててください。また、パスワードがアクセスログやアプリケーションログに表示されないようにしてください。OWASP では、新しいアプリケーションの最初の選択肢としてArgon2の使用を推奨しています。これが利用できない場合は、代わりにPBKDF2またはscryptを使用する必要があります。最後に、上記のいずれも使用できない場合は、bcryptを使用します。

ハッシュ自体も安全ではありません。たとえば、同一のパスワードは同一のハッシュを意味します。これにより、ハッシュルックアップテーブルは多数のパスワードを一度にクラックする効果的な方法になります。代わりに、ソルトハッシュを保存します。ソルトとは、ハッシュの前にパスワードに追加される文字列です。ユーザーごとに異なる(ランダムな)ソルトを使用してください。ソルトは公開値なので、ハッシュとともにデータベースに保存できます。詳しくはこちらをご覧ください。

これは、忘れたパスワードをユーザーに送信できないことを意味します(ハッシュしか持っていないため)。ユーザーを認証していない限り、ユーザーのパスワードをリセットしないでください(ユーザーは、保存された(検証された)メールアドレスに送信されたメールを読むことができることを証明する必要があります)。

セキュリティの質問

セキュリティの質問は安全ではありません-使用しないでください。どうして?セキュリティの質問が行うことは何でも、パスワードの方が優れています。読むPART III:秘密の質問を使用して@Jensローランド答えここでこのウィキインチ

セッションCookie

ユーザーがログインすると、サーバーはユーザーにセッションCookieを送信します。サーバーはCookieからユーザー名またはIDを取得できますが、他のユーザーがそのようなCookieを生成することはできません(TODO説明メカニズム)。

Cookieは乗っ取られる可能性があります。Cookieは、クライアントの他のマシンや他の通信と同じくらい安全です。それらはディスクから読み取られ、ネットワークトラフィックを傍受され、クロスサイトスクリプティング攻撃によって持ち上げられ、ポイズニングされたDNSからフィッシングされて、クライアントがCookieを間違ったサーバーに送信します。永続的なCookieを送信しないでください。Cookieは、クライアントセッションの終了時に終了します(ブラウザが閉じるか、ドメインを離れます)。

ユーザーを自動ログインする場合は、永続的なCookieを設定できますが、フルセッションのCookieとは区別する必要があります。ユーザーが自動ログインし、機密操作のために実際にログインする必要がある追加のフラグを設定できます。これは、シームレスでパーソナライズされたショッピング体験を提供しながら、財務の詳細を保護したいショッピングサイトで人気があります。たとえば、Amazonに戻ったときに、ログインしたように見えるページが表示されますが、注文する(または配送先住所やクレジットカードを変更する)と、確認を求められますあなたのパスワード。

一方、銀行やクレジットカードなどの金融Webサイトは機密データのみを持ち、自動ログインや低セキュリティモードを許可しないでください。

外部リソースのリスト


1
署名付きSSL証明書(blog.startcom.org/?p=145)を取り巻く最近のMITM脆弱性を考えると、SSLとある種のチャレンジレスポンス認証(SRPに代わるものがあります)の組み合わせがおそらくより良いソリューションです。
ケビン・ロニー

このようなものの多くは状況に応じたものです。私はセッションCookieをまったく使用しない傾向があります。cookieがハイジャックされるのは、ほとんどの場合サーバーの障害です。中間の男/よくあるパケット盗聴
Shawn

BCrypt Nugetパッケージ:nuget.org/List/Packages/BCrypt
Fabian Vilers

1
この回答についての注1:これはドラフトであり、wikiとして編集されます。これを編集できる場合は、大歓迎です。
Peter Mortensen、2012

私がよく理解していれば、SRPは複数の当事者の存在に固有です
Webwoman '27

162

まず、この答えはこの正確な質問に最適ではないという強い警告。それは間違いなく最高の答えであってはなりません!

私は先に進み、将来の認証へのより良いアプローチへのアップグレードパスを見つけるという精神で、Mozillaが提案したBrowserID(またはより正確にはVerified Email Protocol)について言及します。

このように要約します。

  1. Mozillaは非営利団体であり、この問題の適切な解決策を見つけることとうまく一致する価値観を持っています
  2. 今日の現実は、ほとんどのWebサイトがフォームベースの認証を使用していることです
  3. フォームベースの認証には大きな欠点があり、フィッシングのリスクが高まります。ユーザーは、ユーザーエージェント(ブラウザ)によって制御される領域ではなく、リモートエンティティによって制御される領域に機密情報を入力するように求められます。
  4. ブラウザーは暗黙的に信頼されているため(ユーザーエージェントの全体的な考えはユーザーに代わって行動することです)、ブラウザーはこの状況の改善に役立ちます。
  5. ここで進行を遅らせる主要な力は、展開のデッドロックです。ソリューションは、いくつかのステップに分解する必要があります。これらのステップは、それ自体でいくつかの段階的な利益をもたらします。
  6. インターネットインフラストラクチャに組み込まれているIDを表現する最も簡単な分散方式は、ドメイン名です。
  7. IDを表現する2番目のレベルとして、各ドメインは独自のアカウントのセットを管理します。
  8. 「アカウント@ドメイン」の形式は簡潔で、幅広いプロトコルとURIスキームでサポートされています。もちろん、そのような識別子は、最も一般的にメールアドレスとして認識されます。
  9. 電子メールプロバイダーは、すでにオンラインの事実上の主要なIDプロバイダーです。現在のパスワードリセットフローでは、通常、アカウントに関連付けられているメールアドレスを制御できることを証明できれば、そのアカウントを制御できます。
  10. 検証済み電子メールプロトコルは、ドメインAにアカウントを持っていることをドメインBに証明するプロセスを合理化するために、公開鍵暗号に基づく安全な方法を提供するために提案されました。
  11. 確認済みメールプロトコルをサポートしないブラウザ(現在はすべて)に対して、Mozillaはクライアント側のJavaScriptコードにプロトコルを実装するシムを提供しています。
  12. 確認済みメールプロトコルをサポートしていないメールサービスの場合、このプロトコルを使用すると、第三者が信頼できる仲介者として機能し、ユーザーがアカウントの所有権を確認したことを証明できます。このような第三者を多数持つことは望ましくありません。この機能は、アップグレードパスを許可することのみを目的としており、電子メールサービスがこれらのアサーションを提供することが非常に推奨されます。
  13. Mozillaは、このような信頼できるサードパーティのように機能する独自のサービスを提供しています。検証済み電子メールプロトコルを実装するサービスプロバイダー(つまり、依拠当事者)は、Mozillaの主張を信頼するかどうかを選択できます。Mozillaのサービスは、確認リンクを含む電子メールを送信する従来の方法を使用して、ユーザーのアカウントの所有権を確認します。
  14. もちろん、サービスプロバイダーは、他の認証方法に加えて、このプロトコルをオプションとして提供することもできます。
  15. ここで求められているユーザーインターフェイスの大きなメリットは、「IDセレクター」です。ユーザーがサイトにアクセスして認証することを選択すると、ユーザーのブラウザーには、サイトで自分を識別するために使用できる電子メールアドレス(「個人」、「仕事」、「政治活動」など)が表示されます。
  16. この取り組みの一環として求められているもう1つの大きなユーザーインターフェイスの利点は、ブラウザーがユーザーのセッション(ユーザーが現在サインインしている主なユーザー)についてよりよく知ることができるようにすることです。
  17. このシステムは分散型であるため、Facebook、Twitter、Googleなどの主要なサイトへのロックインを回避できます。個人は自分のドメインを所有できるため、独自のIDプロバイダーとして機能できます。

これは厳密には「ウェブサイトのフォームベースの認証」ではありません。しかし、これは、フォームベース認証の現在の標準から、より安全なもの、つまりブラウザーでサポートされる認証に移行するための取り組みです。


3
BrowserIDリンクが無効になっている
Mehdi Bounya

プロジェクトはおかしくなっ
Jeff Olson

138

うまく機能していることがわかったこのソリューションを共有したいと思いました。

私はそれをダミーフィールドと呼んでいます(ただし、これを発明したわけではないので、信用しないでください)。

簡単に言う<form>と、これをあなたの中に挿入し、検証時に空であることを確認するだけです:

<input type="text" name="email" style="display:none" />

トリックは、ボットをだまして、必須フィールドにデータを挿入する必要があると考えさせることです。そのため、私は入力に「メール」という名前を付けました。既に使用しているemailというフィールドがある場合は、ダミーフィールドに「company」、「phone」、「emailaddress」などの名前を付けてみてください。不要だとわかっているものを選んで、Webフォームに入力するのが一般的だと思われるものを選んでください。次に、inputCSSまたはJavaScript / jQueryを使用してフィールドを非表示にします。あなたに最適なものを入力してください。入力を設定しないでください。そうしないと、ボットがそのフィールドに分類されません。typehidden

フォーム(クライアント側またはサーバー側のいずれか)を検証するときは、ダミーフィールドが入力されているかどうかを確認して、それが人間またはボットのどちらから送信されたかを確認してください。

例:

人間の場合: ユーザーはダミーのフィールド(私の場合は「email」という名前)を表示せず、入力も試みません。そのため、フォームが送信されたとき、ダミーフィールドの値は空のままである必要があります。

ボットの場合:ボットは、タイプtextと名前email(またはそれと呼ばれるもの)のフィールドを表示し、適切なデータを論理的に入力しようとします。派手なCSSで入力フォームのスタイルを設定してもかまいません。Web開発者は常にそれを行います。ダミーフィールドの値が何であれ、0文字よりも大きい値であれば問題ありません。

ゲストブックでこの方法をCAPTCHAと組み合わせて使用​​しましたが、それ以来、スパム投稿は1つもありません。以前はCAPTCHAのみのソリューションを使用していましたが、最終的には1時間に約5件のスパム投稿が発生しました。フォームにダミーフィールドを追加すると、(少なくとも今までは)すべてのスパムが表示されなくなりました。

これは、ログイン/認証フォームでも問題なく使用できると思います。

警告:もちろん、この方法は100%確実というわけではありません。ボットは、スタイルがdisplay:none適用されている入力フィールドを無視するようにプログラムできます。また、(ほとんどのブラウザに組み込まれているように)オートコンプリートのフォームを使用して、すべてのフォームフィールドを自動入力する人々についても考える必要があります。彼らは同様にダミーフィールドを拾うかもしれません。

また、ダミーフィールドを表示したまま画面の境界の外側に置くことで、これを少し上げることもできますが、これは完全にあなた次第です。

クリエイティブに!


33
これは便利なアンチスパムトリックですが、「メール」以外のフィールド名を使用することをお勧めします。または、ブラウザの自動入力で入力されて、サイトの正規ユーザーを誤ってブロックする場合があります。
Nico Burns

8
私はまた、これらの使用にはいくつかのより多く持っているvisibility:hiddenともposition:absolute;top:-9000px、あなたも行うことができますtext-indentし、またz-indexNONE`と彼らは今の範囲をチェック: -これらの要素のいくつかにと厄介な名前で圧縮されたCSSファイル名にそれらを配置するボットが1display検出することができますので、組み合わせ-私は実際にこれらの方法を使用しており、それらは取引の古いトリックです。+1
TheBlackBenzKid 2012

18
視覚障害のあるユーザーがスクリーンリーダーを使用してフォームをナビゲートするとどうなりますか?
soycharliente

8
ハニーポット:この手法は、名前があるen.wikipedia.org/wiki/Honeypot_(computing)
pixeline

27
インラインスタイリングの必要はありません。フィールドにクラスを追加し(ボットにとって意味のない奇妙な単語を使用する場合があります)、サイトのCSSファイルで非表示にします。Like:<input type="text" name="email" class="cucaracha">およびCSS内:.cucaracha { display:none; }
Ricardo Zea

81

私は上記の答えが「間違っている」とは思わないが、触れられていない認証の広い領域がある(またはむしろ「どのオプションが利用可能で何がトレードであるか」ではなく「Cookieセッションを実装する方法」に重点が置かれている-オフ」。

私の提案された編集/回答は

  • 問題は、パスワードのチェックよりもアカウントのセットアップにあります。
  • 2要素認証の使用は、パスワード暗号化のより賢い手段よりもはるかに安全です。
  • 独自のログインフォームやパスワードのデータベースストレージを実装しようとしないでください。ただし、保存されるデータがアカウントの作成時に無価値であり、自動生成されている場合(つまり、Facebook、FlickrなどのWeb 2.0スタイル)

    1. ダイジェスト認証は、すべての主要なブラウザとサーバーでサポートされている標準ベースのアプローチであり、安全なチャネルを介してもパスワードを送信しません。

これにより、ブラウザ自体が毎回通信を再暗号化するため、「セッション」またはCookieを使用する必要がなくなります。これは最も「軽量な」開発アプローチです。

ただし、公共の低価値サービスを除いて、これはお勧めしません。これは、上記の他の回答の一部に関する問題です。サーバー側の認証メカニズムを再実装しないでください。この問題は解決され、ほとんどの主要なブラウザでサポートされています。クッキーを使用しないでください。手持ちのデータベースには何も保存しないでください。リクエストが認証されているかどうか、リクエストごとに尋ねてください。その他はすべて、構成およびサードパーティの信頼できるソフトウェアによってサポートされる必要があります。

そう ...

まず、最初にアカウント(パスワードを使用)を作成することと、その後にパスワードを再確認することを混同しています。私がFlickrで初めてサイトを作成する場合、新しいユーザーはゼロの値(空白のWebスペース)にアクセスできます。アカウントを作成した人が自分の名前について嘘をついていても、私は本当に気にしません。私は病院イントラネット/エクストラネットのアカウントを作成していた場合は、すべての医療記録の値の嘘、と私はそうやるアカウントの作成者の身元(*)気を。

これは非常に難しい部分です。唯一まともな解決策は、信頼のウェブです。たとえば、医師として病院に参加したとします。写真、パスポート番号、公開鍵を使用してどこかでホストされるWebページを作成し、それらすべてを秘密鍵でハッシュします。次に、病院を訪問し、システム管理者がパスポートを見て、写真があなたに一致するかどうかを確認し、病院の秘密キーでWebページ/写真のハッシュをハッシュします。これからは、キーとトークンを安全に交換できます。病院を信頼する人なら誰でもそうです(秘密のソースBTWがあります)。システム管理者は、RSAドングルまたはその他の2要素認証も提供できます。

しかし、これはある多くの手間はなく、非常にウェブ2.0の。ただし、これは、自己作成されていない貴重な情報にアクセスできる新しいアカウントを作成する唯一の安全な方法です。

  1. KerberosとSPNEGO-信頼できるサードパーティによるシングルサインオンメカニズム-基本的に、ユーザーは信頼できるサードパーティに対して検証します。(これは決して信頼できるOAuthではありません)

  2. SRP-信頼できるサードパーティなしの巧妙なパスワード認証。しかし、ここでは「2要素認証を使用した方がコストが高くても安全です」という領域に入ります。

  3. SSLクライアント側-クライアントに公開鍵証明書を提供します(すべての主要なブラウザーでサポートされていますが、クライアントマシンのセキュリティについて質問があります)。

結局のところ、それはトレードオフです-セキュリティ違反のコストと、より安全なアプローチを実装するコストとは何ですか。ある日、適切なPKIが広く受け入れられるようになり、独自のロール認証フォームとデータベースがなくなる可能性があります。ある日...


29
「上記の答えは「間違っている」とは思わない」でどの答えについて話しているのか
わかりにくい

55

ハッシュするときは、MD5などの高速ハッシュアルゴリズムを使用しないでください(多くのハードウェア実装が存在します)。SHA-512などを使用します。パスワードの場合、ハッシュは遅い方が良いです。

ハッシュをより速く作成できるほど、ブルートフォースチェッカーの動作が速くなります。したがって、ハッシュが遅いほどブルートフォースが遅くなります。遅いハッシュアルゴリズムは、長いパスワード(8桁+)に対してブルートフォースを強制することを非現実的にします


5
SHA-512も高速であるため、数千回の反復が必要です。
Seun Osewa

5
「高速ハッシュアルゴリズムを使用しないでください...低速なハッシュの方が良いです」-説明?ドキュメンテーション?
one.beat.consumer 2012

17
説明:ハッシュを作成する速度が速ければ速いほど、ブルートフォースチェッカーの動作が速くなります。したがって、ハッシュが遅いほどブルートフォースが遅くなります。遅いハッシュアルゴリズムでは、長いパスワード(8桁+)に対してブルートフォースを強制することは実用的ではありません
NickG

6
ゆっくりハッシュするように設計されたbcryptのようなものに似ています。
Fabian Nicollier

4
別の回答で述べたように、「OWASPはArgon2を新しいアプリケーションの最初の選択肢として使用することをお勧めします。これが使用できない場合は、代わりにPBKDF2またはscryptを使用する必要があります。最後に、上記のいずれも使用できない場合は、bcryptを使用してください。」MD5もSHAハッシュ関数も、パスワードのハッシュに使用しないでください。この答えは悪いアドバイスです。
Mike



25

多層防御に基づいて、使用した提案を1つ追加します。管理者は通常のユーザーと同じ認証と認証システムを使用する必要はありません。高い特権を付与するリクエストに対して個別のコードを実行する個別のURLに個別のログインフォームを設定できます。これは、通常のユーザーにとって大変な苦痛になる選択をすることができます。私が使用したものの1つは、管理者アクセス用のログインURLを実際にスクランブルし、管理者に新しいURLを電子メールで送信することです。新しいURLは恣意的に困難(非常に長いランダム文字列)になる可能性があるため、ブルートフォース攻撃を即座に停止しますが、管理ユーザーの唯一の不便は、メールのリンクをたどることです。攻撃者は、どこにPOSTするかさえわからなくなります。


電子メールは安全ではないため、電子メール内の単純なリンクは実際には安全ではありません。
David Spector

2要素ではない他のトークンベースのパスワードリセットシステムと同じくらい安全です。それらのほとんどすべてです。
Iain Duncan

17

これを回答として回答するのか、コメントとして回答するのが最善だったのかわかりません。私は最初のオプションを選びました。

poing パートIV:最初の回答の忘れられたパスワード機能について、タイミング攻撃について指摘します。

では、あなたのパスワードを覚えておいてくださいフォームを、攻撃者は電子メールの完全なリストを確認し、(下記リンク参照)をシステムに登録されて検出することができました。

Forgotten Password Formに関して、遅延関数を使用して、成功したクエリと失敗したクエリの時間を同じにすることをお勧めします。

https://crypto.stanford.edu/~dabo/papers/webtiming.pdf


14

私は非常に重要なコメントを1つ追加したいと思います。

  • 企業の イントラネット環境では」、前述のすべてではないにしてもほとんどが当てはまらない可能性があります。

多くの企業は、「内部使用のみ」のWebサイトを展開しています。これは、事実上、「企業アプリケーション」であり、URLを介して実装されています。これらのURLは(おそらく...)「会社の内部ネットワーク」内でのみ解決できます。(どのネットワークには、VPN接続されたすべての「ロードウォリアー」が魔法のように含まれています。)

ユーザーが前述のネットワークに忠実に接続されている場合、ユーザーのID (「認証」)は[既に...]「決定的に知られている」、特定のことを行うための許可(「承認」)は...などです。 ..「このウェブサイトにアクセスするには」

この「認証+承認」サービスは、LDAP (Microsoft OpenDirectory)やKerberos などのいくつかの異なるテクノロジーによって提供できます。

あなたの視点から見ると、あなたは単にこれを知っています:あなたのウェブサイトを正当に巻き上げる人は誰でも [魔法のように含んでいる環境変数...] "トークン"を伴わなければならないということです。(つまり、そのようなトークンがないことは、の直接の根拠でなければなりません404 Not Found。)

トークンの値はあなたには意味がありませんが、必要に応じて、「適切な手段が存在する」ことで、あなたのウェブサイトは「(権威的に)知っている人に(LDAP ...など)」あらゆるものについて尋ねることができます(!)あなたが持っているかもしれない質問。言い換えれば、あなたはないではないの自分自身を役に立つ任意の「ホーム・成長ロジック。」代わりに、当局に問い合わせ、暗黙のうちにその評決を信頼します。

Uhハァッ...それはだかなりの精神的・スイッチ「ふんわり野生と-インターネット。」


9
子供ほどよく句読点に落ちましたか?:)私はそれを3回読みましたが、どの時点であなたが作ろうとしているのかはまだ分かりません。しかし、「フォームベースの認証が不要な場合もあります」という場合は、そのとおりです。しかし、いつそれが必要なのかを検討していることを考えると、なぜこれが非常に重要であるのかわかりませんか?
Hugo Delsing 2015

1
私のポイントは、企業の外部の世界は内部の世界とはまったく異なるということです 「ウーリーワイドウェブ」にアクセスできるアプリを作成していて、一般の人が一般に利用できるようにするには、独自の認証方法と承認方法を導入するしかありません。しかし、そこに到達するための唯一の方法またはVPNを使用することである企業内では、アプリケーションがこれらのことを実行するための「独自の」メソッドを持っていない(持っててはならない)可能性が非常に高いです。アプリ、一貫した集中管理を提供するために、代わりにこれらのメソッドを使用する必要があります。
マイクロビンソン

2
イントラネットでさえ、建物に最低限のセキュリティが必要です。営業には機密の利益と損失の数値があり、エンジニアリングには機密の知的財産があります。多くの企業は、部門や部門の境界を越えてデータを制限しています。
Sablefoste 2017

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.