私が取り組んでいるWebアプリケーションは、100%SSLで保護されています(または、今日呼ばれているTLSです)。このアプリケーションは最近セキュリティ会社によって監査されました。私はほとんど彼らの結果に同意しますが、大きな議論につながった1つのことがありました:
ユーザーのパスワード変更プロセスの一環として、ユーザーは古いパスワードと新しいパスワードを2回提供する必要があります。それに加えて、新しいパスワードはパスワードポリシー(最小長、yadda yadda)に準拠する必要があります。
アプリケーションはVaadinで実現され、小さなAJAX=メッセージを使用してUIを更新します。アプリケーションのロジック全体がサーバー上に存在します。これは、パスワード変更フォームのすべての検証がサーバー上で行われることを意味します。フォームを検証するために、古いパスワードと2つの新しいパスワード(もちろん一致する必要があります)の両方をサーバーに送信する必要があります。何か問題がある場合(古いパスワードが間違っている場合は、新しいパスワードが一致しない、新しいパスワードがパスワードポリシーに準拠していない)場合、ユーザーはエラーになります。残念ながら、同期プロセスの一部として、Vaadinはすべてのフォームデータ(古いパスワードと新しいパスワードを含む)を再度クライアントに送信します。 =
これはすべてSSLを介して行われるため、私はそれについて2度考えたことはありませんでしたが、セキュリティ会社はこれを最も重大なセキュリティリスクと見なしていました。セキュリティ会社の視点での問題は、データがサーバーに送信されることではなく、検証が失敗した場合にサーバーが応答にデータを含めることであることに注意してください。したがって、現在の解決策は、検証が失敗した場合にすべてのフィールドを空にすることです。たとえば、パスワードが繰り返しパスワードポリシーに一致しない場合、ユーザーは3つのテキストフィールドに何度も入力する必要があるため、ユーザーエクスペリエンスが低下します。
私はこれが一番上だと思ってナイーブですか?つまり、攻撃者が暗号化を破った場合でも、攻撃者はトラフィック全体にアクセスできます。
edit:ショルダーサーフィンに関してパスワードがユーザーにエコーバックされないであることを明確にしたいと思います。すべての入力フィールドは、プレースホルダーのみを表示し、実際の文字は表示しない適切なパスワードフィールドです。
実際には、フィールドをクリアする方がUXが優れていると私は主張します。パスワードフィールドがアスタリスクでいっぱいであると仮定すると、ユーザーはパスワードを再入力したときにフィールド全体を削除します。
さらに、新しいセキュリティリスクに自分自身を開放します。 XSS、ショルダーサーフィン、および一般的にリスクが高まった場所にパスワードを送信する可能性があります。
間違った情報を入力した場合、パスワードフィールドに入力したままのサイトにアクセスしたことはありません。入力されたonlyフィールドは電子メールフィールドであり、場合によってはアドレス/電話番号でした。
常に最悪の事態を想定する必要があり、穴を塞ぐことができる場合はそうする必要があります。特にこれは本当に存在しないUXの問題の簡単な修正であるため、セキュリティ監査人が上位にいるとは思いません。パスワードを送り返し、各文字をアスタリスクに変更せずに表示する場合は、次に、あなたは間違いなくセキュリティ上の問題を抱えています。入力したパスワードが誰かに表示されるのは、一時的に表示するオプションを選択した場合のみです。
パスワードのポリシーは入力のみで、出力はしないことをお勧めします。これは実用的なアプローチであり、コストをほとんどかけずにセキュリティを確保するための適切な手順です。
「ソースの表示」をクリックすると、パスワードの出力もプレーンテキストで表示されます。つまり、周りのショルダーサーファーがパスワードを表示できます。
ユーザーに元のパスワード、新しいパスワード、および確認の再入力を求めるだけの場合、これは大きなUIの欠陥ではありません。それが大規模なページであり、他のフィールドの検証によってパスワードボックスが空白になる場合、これはユーザーが毎回3つのパスワードを再入力するのを煩わしくする可能性があり、一部のユーザーは単にqwerty
か何か。この場合は、パスワードフィールドを別のページに移動して、個別に入力および検証できるようにします。
入力をクライアントにエコーバックすると、常にクロスサイトスクリプティングXSSの疑いが生じます。しかし、あなたの場合、出力は一時的であり、それを入力した人以外には表示されないので、それは過剰な反応だと思います。パスワードとして<script>alert(document.cookie);</script>
を試しましたか?
パスワード全体を変更してAjax自体を呼び出し、フォームをクリアしたりページを変更したりしないことで、監査人とゲームをすることができます。エラーコードで応答するだけで、それに応じてUIを調整できます。このようなもの:
古いパスワードは、試行が失敗するたびに古くなることに注意してください。古いパスワードは、正当なユーザーが変更を加えることを保証するためにあります。 「再利用」すればするほど、確実性は弱まります。試行がN回失敗した後(またはN秒後)、すべてをクリアする必要があります。
パスワードをクライアントに送り返すことが安全でないと考えられている理由は、クライアントがページをキャッシュする可能性があるためです。つまり、ユーザーのローカルドライブのどこかに平文でパスワードのバージョンが保存されているためです。 [戻る]ボタンを押すか、キャッシュを解析すると、パスワードが明らかになる可能性があります。これは特に公共のマシンでは悪いです。
また、OPが提案することを実行したい場合がある有効なシナリオもあります。たとえば、CAPTCHAが表示された登録画面がある場合、ユーザーが2回パスワードを入力し直すと、CAPTCHAが失敗するたびに煩わしく感じる可能性があります。ただし、サイトがセキュリティ監査を必要とするほど重要である場合は、これを回避したほうがよいでしょう。代わりに、キャプチャを簡単にすることを検討してください。
3つのパスワードを再入力してもユーザーエクスペリエンスが悪いとは思わないので、返送しないようにしてください。
ユーザーがコンピューターを離れ、他の誰かがconsole.log($('#oldpassword').val());
のようなことをすることを想像してください。それは悪いことです。
パスワードのフィールドにはドットしか表示されませんが、最後の文字を忘れた場合は、通常、フィールド全体をクリアするため、パスワード全体を再入力します。
SSL通信は復号化が難しいため、ノード間で何が転送されていますか?それはあなたの首に冷たい感じを与え、あなたの機密データが走り回っていて、誰もそれを制御していないことを知っています。
だからあなたがサーバー側でパスワードをクリアしているなら、それをやり続けてください!!ヴァディンに勝たせないでください。そしてクライアント側では常に賢明なデータを破棄します。