これを読む前にヨアヒムの答えを読んでください。彼は、クライアント側の脆弱性の背後にある一般的な理由をカバーしています。さて、この問題を回避する方法を提案するために...
リクエストごとにサーバーで手動で認証する必要のないクライアント/サーバー通信の安全なスキーム:
あなたはしている今でも、サーバーが最後の発言権を持っせ、およびサーバは、まだクライアントが言うすべてを検証するために持っているが、それは透過的に行われます。
HTTPSプロトコルを想定して、中間者攻撃(MITMA)を防ぎます。
クライアントは初めてサーバーとハンドシェイクし、サーバーはクライアントの公開鍵を生成し、非対称暗号化スキームを使用して秘密鍵を保持します。クライアントは、サーバーの「公開」キーをローカルストレージに保存し、どこにも保存しない安全なパスワードで暗号化します。
これで、クライアントはオフラインになりました。クライアントは信頼できるアクションを実行したいと考えています。クライアントはパスワードを入力し、サーバーの公開キーを取得します。
クライアントはそのデータの知識に基づいてアクションを実行し、クライアントは実行するすべてのアクションをそのクライアントのサーバーの公開キーで暗号化します。
クライアントがオンラインの場合、クライアントはクライアントIDを送信し、クライアントが実行したすべてのアクションは、サーバーの公開キーで暗号化されたサーバーに送信されます。
サーバーはアクションを解読し、それらが正しい形式である場合、クライアントで発生したことを信頼します。
注意:
クライアントのパスワードをどこにも保存することはできません。そうしないと、攻撃者はキーを取得し、独自のアクションに署名することができます。このスキームのセキュリティは、サーバーがクライアント用に生成するキーの整合性のみに依存します。そのキーを要求するとき、クライアントはまだサーバーで認証される必要があります。
実際には、クライアントではなくセキュリティをサーバーに依存しています。クライアントが実行するすべてのアクションは、サーバーで検証する必要があります。
Web Workerで外部スクリプトを実行することが可能です。あなたが持っているすべての JSONPリクエストは、今やはるかに大きなセキュリティ問題になっていることに留意してください。すべてのコストでキーを保護する必要があります。紛失すると、攻撃者はユーザーになりすますことができます。
これは、「サーバーへのpingを実行しない」という要求を満たします。攻撃者は、鍵を知らない場合、偽造データでHTTPリクエストを単純に模倣することはできません。
ヨアヒムの答えはまだ正しい。実際には、サーバーですべての認証を実行しています。ここで保存した唯一のものは、毎回サーバーでのパスワード検証の必要性です。これで、コミットするとき、または更新されたデータをプルするときにのみサーバーに関与する必要があります。ここで行ったのは、クライアント側で信頼できるキーを保存し、クライアントにそれを再検証させることだけです。
これは、単一ページアプリケーション(AngularJSなど)の非常に一般的なスキームです。
サーバーの公開鍵をRSAのようなスキームで何を意味するのかを「公開」と呼びますが、実際にはスキーム内の機密情報であり、保護する必要があります。
パスワードをメモリ内のどこにも保管しません。ユーザーがオフラインコードの実行を開始するたびに、「オフライン」パスワードを送信するようにします。
独自の暗号を転がさないでください -認証にはスタンフォード大学のような既知のライブラリを使用してください。
このアドバイスをそのままお使いください。実際のビジネスに不可欠なアプリケーションでこの種の認証を行う前に、セキュリティの専門家に相談してください。これは深刻な問題であり、苦痛であり、間違いを起こしやすいものです。
他のスクリプトがページにアクセスできないことが重要です。つまり、Webワーカーで外部スクリプトのみを許可します。ユーザーがパスワードを入力したときにパスワードを傍受する可能性のある他の外部スクリプトを信頼することはできません。
使用prompt
していない、あなたが完全にわからないと(それはイベントがそれへのアクセス権を持っていますが、唯一の同期コード内のポイントへのライブべきではない)その実行延期しない場合は、インラインパスワードフィールドを。また、実際にはパスワードを変数に保存しないでください。これも、ユーザーのコンピューターが危険にさらされていないことを信頼する場合にのみ機能します(ただし、サーバーに対する検証についても同様です)。
クライアントをまだ信用していないことを付け加えたいと思います。クライアントだけを信頼することはできません。Joachimの答えはそれを否定すると思います。作業を開始する前にサーバーをpingする必要がないという利便性のみを得ました。
関連資料: