34

将来の Web アプリ (Angularjs) とモバイル アプリ (iOS/Android) で使用できる RESTful API (Python/Flask) を開発する計画を立てる必要があります。

私は 3 日間調査してきましたが、いくつかのシナリオに遭遇しました。HTTPS を使用することは、以下の方法に加えて安全性を維持する 1 つの方法です。しかし、https は遅いため、より高速で高価なサーバーが必要になる可能性があります。

  1. Basic-Http-Auth を使用し、API へのすべてのリクエストに対してネットワーク経由でユーザー名/パスワードをプレーン (まだ https) で送信します。
  2. パスワードのハッシュである Digest-Auth を使用すると、追跡が自動化されます。これは Web アプリでは機能しますが、iPhone と Android がこれをネイティブにサポートするかどうかは確認できませんでした。もしそうなら、それは簡単な解決策かもしれません!
  3. カスタム http ヘッダーを使用して、認証が成功したときに http ヘッダーでカスタム認証文字列を送信します。ただし、ユーザーが行うすべてのリクエストに対してこの認証コードを送信していることを確認する必要があります。これにより、1) とまったく同じになりますが、単純なパスワードは使用されず、認証コードはリスクなしで期限切れになるという違いがあります。また、2) のように自動化されなくなった認証コードの追跡にも問題があります。
  4. OAuth の使用はオプションです。しかし、設定がかなり難しいです。他に良い方法がない場合、それが唯一の方法でしょうか?
  5. この素晴らしい記事で説明されているように、Amazon S3 のような API を保護します。要するに、サーバーとクライアントの両方が秘密鍵を知っており、それを使用して通信をハッシュすると彼は言います。配達員がギャングスタの握手を知っている場合にのみ信頼できるというのは、ヤクザの握手のようなものです。誰かが尋ねるコメントをさらに下に:

純粋な HTML5 アプリで秘密鍵を「安全」に保つ方法は?

あなたはまさにその通りです。純粋な HTML5 (JS/CSS/HTML) アプリでは、キーの保護はありません。HMAC の必要性や複雑さなしに、標準の API_KEY またはその他の使いやすい識別子を使用してクライアントを安全に識別できるため、キーは必要ありません。

つまり、そもそも Web アプリにメソッドを使用しても意味がありません。そして正直なところ、これがモバイルデバイスでどのように機能するかわかりません。ユーザーが私たちのアプリをダウンロードし、秘密鍵を iPhone からサーバーに送信するにはどうすればよいですか? 転送した瞬間、危うくなります。

調べれば調べるほど優柔不断になる。

以前にこれを行ったことがあり、その経験を共有できるプロに尋ねたいと思っていました. どうもありがとう

4

3 に答える 3

67

2 つの異なる概念を混同/統合しているようです。トラフィックの暗号化 (HTTPS) について話し始め、次に、認証されたセッションを管理するさまざまな方法について話し始めます。安全なアプリケーションでは、これらは相互に排他的なタスクではありません。また、セッション管理が認証にどのように影響するかについて誤解されている可能性もあるようです。これに基づいて、Web アプリケーション/Web API セッション管理、認証、および暗号化に関する入門書を提供します。

序章

セッション管理

HTTP トランザクションはデフォルトでステートレスです。HTTP は、HTTP 要求が特定のユーザー (認証されているかどうかにかかわらず) から送信されたことをアプリケーションに知らせる方法を指定していません。

堅牢な Web アプリケーションの場合、これは受け入れられません。複数のリクエストにわたって行われたリクエストとデータを関連付ける方法が必要です。これを行うには、サーバーへの最初のリクエストで、ユーザーに「セッション」を割り当てる必要があります。通常、セッションには、クライアントに送信されるある種の一意の ID があります。クライアントはすべてのリクエストでそのセッション ID を送信し、サーバーはすべてのリクエストで送信されたセッション ID を使用して、ユーザーへの応答を適切に準備します。

「セッションID」は他の多くのものと呼ばれることがあることを覚えておくことが重要です。それらのいくつかの例: セッション トークン、トークンなど。一貫性を保つために、この応答の残りの部分では「セッション ID」を使用します。

クライアントからの各 HTTP 要求には、セッション ID を含める必要があります。これは多くの方法で行うことができます。一般的な例は次のとおりです。

  1. Cookie に保存できます。現在のドメインの Cookie は、リクエストごとに自動的に送信されます。
  2. URL で送信できます - 各リクエストは URL でセッション ID を送信できますが、セッション ID はクライアントの履歴に残るため、推奨されません。
  3. HTTPヘッダーとして送信できます-各リクエストでヘッダーを指定する必要があります

ほとんどの Web アプリケーション フレームワークは Cookie を使用します。ただし、JavaScript と単一ページの設計に依存するアプリケーションは、HTTP ヘッダーを使用するか、サーバーが監視できる他の場所に保存することを選択する場合があります。

クライアントにセッション ID を通知する HTTP 応答と、セッション ID を含むクライアントの要求は完全にプレーン テキストであり、100% 安全ではないことを覚えておくことは非常に重要です。これに対抗するには、すべての HTTP トラフィックを暗号化する必要があります。そこで HTTPS の出番です。

システム内の特定のユーザーにセッションをリンクすることについては触れていないことを指摘することも重要です。セッション管理は、システムにアクセスする特定のクライアントにデータを関連付けるだけです。クライアントは認証済みの状態と認証されていない状態の両方になることができますが、どちらの状態でも通常はセッションがあります。

認証

認証は、セッションをシステム内の特定のユーザーにリンクする場所です。これは通常、ユーザーが資格情報を提供し、それらの資格情報が検証され、システム内の特定のユーザー レコードにセッションをリンクするログイン プロセスによって処理されます。

ユーザーは、アクセス制御リストとアクセス制御エントリ (ACL および ACE) を介して、きめ細かいアクセス制御の特権に関連付けられます。これは一般に「承認」と呼ばれます。ほとんどのシステムには、常に認証と承認の両方があります。一部の単純なシステムでは、認証されたすべてのユーザーが同等であり、その場合、単純な認証を超える承認はありません。これに関する詳細は、この質問の範囲外ですが、ACE/ACL について読むことを検討してください。

特定のセッションは、さまざまな方法で認証されたユーザーを表すものとしてフラグを立てることができます。

  1. サーバー側に保存されたセッションデータは、ユーザーID /使用が特定のユーザーとして認証されていることを示すその他のフラグを保存できます
  2. セッション ID と同じように、別のユーザー トークンをクライアントに送信できます (暗号化されていない HTTP では、暗号化されていないセッション ID を送信するのと同じくらい安全ではありません)。

どちらのオプションでも問題ありません。それは一般的に、あなたが取り組んでいるテクノロジーと、それらがデフォルトで提供するものに帰着します.

通常、クライアントは認証プロセスを開始します。これは、資格情報を特定の URL (例: yoursite.com/api/login) に送信することで実行できます。ただし、「RESTful」になりたい場合は、通常、リソースを名詞で参照し、「作成」のアクションを実行します。これは、資格情報の POST を yoursite.com/api/authenticatedSession/ に要求することで実行できます。認証されたセッションを作成するという考えはどこにありますか。ほとんどのサイトは、認証情報を /api/login などに POST するだけです。これは「真の」または「純粋な」RESTful の理想からの逸脱ですが、ほとんどの人はこれを「認証されたセッションを作成する」と考えるよりも単純な概念だと考えています。

暗号化

HTTPS は、クライアントとサーバー間の HTTP トラフィックを暗号化するために使用されます。認証されたユーザーと認証されていないユーザーに依存するシステムでは、認証されているユーザーに依存するすべてのトラフィックを HTTPS で暗号化する必要があります。これを回避する方法はありません。

この理由は、ユーザーを認証し、シークレット (セッション ID など) を共有し、そのシークレットをプレーンな HTTP でパレードし始めると、中間者攻撃によってセッションがハイジャックされる可能性があるためです。ハッカーはトラフィックが監視対象のネットワークを通過するのを待ち、シークレットを盗み (HTTP 経由のプレーン テキストであるため)、元のクライアントになりすましてサーバーへの接続を開始します。

これに対抗する 1 つの方法は、リクエストのリモート IP アドレスを認証済みセッションに関連付けることです。これだけでは効果がありません。ハッカーは、偽のリクエストでリモート IP アドレスを偽装し、サーバーが送り返す応答を観察できるからです。ほとんどの人は、履歴データを追跡し、それを使用して特定のユーザーのログイン パターンを特定する (Google のように) 場合を除き、これを実装する価値さえないと主張するでしょう。

サイトを HTTP セクションと HTTPS セクションに分割する必要がある場合は、HTTP トラフィックがセッション ID またはユーザーの認証ステータスを管理するために使用されるトークンを送受信しないことが不可欠です。また、HTTP 以外の要求/応答内で機密性の高いアプリケーション データを送信しないことも重要です。

Web アプリケーション/API 内のデータを保護する唯一の方法は、トラフィックを暗号化することです。

トピックを 1 つずつ

Basic-Http-Auth

  • 認証: はい
  • セッション管理: いいえ
  • 暗号化: いいえ

これは、Web リソースのみで認証する方法です。基本認証は、URL によって識別されるリソースによって使用を認証します。これは、.htaccess ベースのディレクトリ/ロケーション認証を使用して、Apache HTTP Web サーバーによって最も一般的に実装されました。クレデンシャルはリクエストごとに送信する必要があります。通常、クライアントはこれをユーザーに対して透過的に処理しました。

基本認証は、認証モードとして他のシステムで使用できます。ただし、Basic-Http-Auth を利用するシステムは、Basic-Http-Auth 自体ではなく、認証とセッション管理を提供しています。

  • これはセッション管理ではありません。
  • これは暗号化ではありません。コンテンツと認証情報はほぼ 100% プレーン テキストです
  • これは、アプリケーションの HTTP 要求/応答の内容を保護しません。

ダイジェスト認証

  • 認証: はい
  • セッション管理: いいえ
  • 暗号化: いいえ

これは Basic-Http-Auth とまったく同じですが、いくつかの単純な MD5 ダイジェストが追加されています。暗号化を使用する代わりに、このダイジェストに依存しないでください。

  • これはセッション管理ではありません。
  • これは暗号化ではありません。ダイジェストは壊れやすい
  • これは、アプリケーションの HTTP 要求/応答の内容を保護しません。

OAuth

  • 認証: はい
  • セッション管理: いいえ
  • 暗号化: いいえ

OAuth では、外部サービスに資格情報を検証させるだけです。その後、OAuth プロバイダーへの認証リクエストの結果を管理/操作するのはあなた次第です。

  • これはセッション管理ではありません。
  • これは暗号化ではありません。サイトのトラフィックはプレーン テキストのままです。認証プロセスは HTTPS の制限により安全ですが、アプリケーションは依然として脆弱です。
  • これは、アプリケーションの HTTP 要求/応答の内容を保護しません。

ギャングスター ハンドシェイク/カスタム HTTP ヘッダー

  • 認証: はい、潜在的に
  • セッション管理: はい、潜在的に
  • 暗号化: いいえ

「カスタム HTTP ヘッダー」は「ギャング ハンドシェイク」の一種です。そのため、同じセクションを使用してそれらについて説明します。唯一の違いは、「カスタム HTTP ヘッダー」が hanshake (セッション ID、トークン、ユーザー認証トークンなど) を格納する場所 (つまり、HTTP ヘッダー) を指定していることです。

これらは、認証の処理方法やセッション管理の処理方法を指定していないことに注意してください。それらは基本的に、セッション ID/認証トークンが保存される方法と場所を記述します。

認証は、アプリケーションまたはサードパーティ (OAuth など) を介して処理する必要があります。セッション管理も同様に実装する必要があります。興味深いのは、必要に応じて 2 つのマージを選択できることです。

  • これは暗号化ではありません。サイトのトラフィックはプレーン テキストのままです。OAuth を使用する場合、HTTPS 制限により認証プロセスは安全になりますが、アプリケーションは依然として脆弱です。
  • これは、アプリケーションの HTTP 要求/応答の内容を保護しません。

するべきこと

...安全な堅牢な Web アプリケーションには次のものが必要であることを理解しておくことを強くお勧めします。

  1. 暗号化 (ほとんどの場合、HTTPS が唯一の選択肢です)
  2. セッション管理
  3. 認証・認可

承認は認証に依存します。認証はセッション管理に依存し、暗号化はセッションがハイジャックされず、資格情報が傍受されないようにします。

フラスコログイン

ホイールの再実装を避ける方法として、flask-loginを調べる必要があると思います。私は個人的にそれを使用したことはありません (私は Python で Web アプリケーションにピラミッドを使用しています)。ただし、以前に Web アプリケーション/Python ボードで言及されているのを見たことがあります。認証とセッション管理の両方を処理します。HTTPS 経由で Web API/アプリケーションをスローすると、3 つすべて (暗号化、セッション管理、およびユーザー認証) が得られます。

フラスコログインを使用しない/使用できない場合は、独自に作成する準備をしてください。ただし、安全な認証メカニズムを作成する方法について最初に調査してください。

可能な限り、認証手順の書き方を理解していない場合は、ハッカーがパターンベースの攻撃やタイミング攻撃などをどのように使用するかを最初に学ばない限り、試みないでください。

トラフィックを暗号化してください

...「巧妙な」トークンの使用で HTTPS の使用を避けることができるという考えを超えてください。「遅い」、プロセスが集中するなどの理由で、HTTPS/暗号化の使用を避ける必要があるという考えを超えてください。これは暗号化アルゴリズムであるため、プロセスが集中します。ユーザーのデータとアプリケーション データの安全性を確保する必要性は、常に最優先事項である必要があります。ユーザーのデータが危険にさらされたことをユーザーに通知するという恐怖を経験したくはありません。

于 2013-06-03T20:44:33.383 に答える
1

httpsの方が遅いですが、そうではありません。ハンドシェイクだけが遅くなります。私たちにとって最大の問題は、サーバーモバイル側でキーペアと権利を維持することです。メッセージダイジェストも実装しました。問題は、php-android-ios のバージョンを適切に設定するのが難しいことです。これが完了した後 (パラメーターは、最初に Android 側でのみ結果が Google に示唆されているものを変更する必要があります)、問題はローエンド デバイスで発生します。CPU 使用率が高く、復号化/暗号化プロセスが遅く、https よりもはるかに遅く、特に、10kb の文字列を変換する必要がある場合 (数分かかることがあります)。

Nasa のデータをハマスに転送しない場合は、単純な HTTP を介した非常に単純な暗号化を使用するよりも、ビットを反転するなど...

于 2013-05-13T10:49:04.597 に答える