54

Web サービスと通信するモバイル アプリ (現在は IOS、まもなく Android) があります。ログインはなく、データは非公開ではありません。基本的に、アプリはマーカー (経度、緯度) を POST し、最も近い 25 個のマーカーを取得してマップに表示します。

これは非常に些細なアプリであり、この Web サービスを悪用することに多大な労力を費やす人がいるとは思えません。しかし、多くのマーカーを POST することには、誰かにとっての楽しみがあることがわかります。私が最も懸念しているのは、多くのリクエストをプッシュするスクリプトを実行している誰かです (高価な帯域幅を使用し、アプリ データを無意味にしています)。

私はゆっくりと、これは安全ではないという結論に達しています。最良の答えは「これをしないでください」です。認証なしで Web サービスを提供しないでください。こんなにオープンなサービスはなかなかありません。Google の You Tube API は公開されていますが、ほとんどは公開されていません。残念ながら、仕方がありません。それで、これを何日も見た後、これが私の考えです。私はセキュリティの専門家とはかけ離れており、私のアプローチは改善できると確信しています。しかし、それはあなたを正しい方向に向けるかもしれません。うまくいけば、より経験豊富な誰かが参加して、これを修正/改善するかもしれません. この記事とコメントは特に役に立ちました。

メッセージ レベルのセキュリティ

ハッシュ暗号化でメッセージを保護します。クライアントと Web サービスはすべて、URL とすべての POST 引数からハッシュを作成するためのソルトとして使用される共有シークレットのコピーを保持します。ハッシュは追加の引数として渡され、ハッシュは再構築され、反対側で比較されます (共有キーをソルトとして使用)。これは、モバイル クライアント コードを数分でリバース エンジニアリングできることを理解するまでは、非常に良いことです。その時点で、この防衛線はまったく役に立ちません。

クライアント対策

クライアントには、正当なユーザーによって送信されるメッセージの数を制限する手段として、メッセージのレート制限が含まれています。これもまた、モバイル デバイスをジェイルブレイクする攻撃者に対しては役に立ちません。

サーバー側のセキュリティ

そのため、クライアント (および共有シークレット) が危険にさらされているという前提で独立するために、サーバー側はできるだけ多くの追加のセキュリティ対策を講じる必要があります。ここに私が持っているものがあります:

1 つのメッセージ引数は、リプレイ攻撃を制限するために使用される UTC 時間です。これにより、攻撃者がサーバーで同じメッセージを繰り返し送信するのを防ぐことができます。

サーバーは IP によるレート制限を行います。はい、IP は簡単にスプーフィングされ、プロキシ スイッチングはチャイルド プレイですが、IP がほとんどない場合はすべてが役に立ちます。

もちろん、サーバーはすべての引数を厳密に検証し、パラメーター化されたクエリを使用し、例外を返しません。

トランスポート レベルのセキュリティ

残念ながら、登録プロセスなしでは個々のクライアント SSL 証明書を発行することはできないと確信しています。また、私は msg ハッシュ チェックを使用しているため (そして私のデータは非公開ではないため)、SSL がテーブルに何をもたらすのか完全にはわかりません。ただし、SSL を使用すると、簡単かつ安価に展開できる別のレベルのセキュリティが追加されるためです (メッセージごとに追加の接続時間がかかりますが)。

私のアプローチでぽっかり大きな大きな穴

アプリが人気になった場合、誰かがクライアントの共有秘密を侵害する可能性があると警告されています. 彼らができるという理由だけで、彼らはおそらくそれをインターネットに投稿するでしょう. したがって、実際にはすべてサーバー側にかかってきます。残念ながら、攻撃者を特定してブロックする方法はありません。これは私が心から愛するでしょう。

最後の嘆願

数日間の調査の後、これが私が持っているすべてです。でももっと欲しい。サーバー側を強化するためのアイデアがあれば特に感謝します。だから、私はすべてのSOポイントを賞金として上げました. はい、全部で97点!

4

8 に答える 8

23

実際、あなたの特定のケースでは、現在 iOS のみのアプリであるため、解決策があります。

  1. ユーザーが初めてアプリをダウンロードして実行した後、アプリ/access_token/createは GUID を取得する API にヒットし、Apple のプッシュ通知を介してそれをアプリケーションに中継します。

  2. アプリはこの access_token を保存し、後続のすべてのリクエストで使用します。実際の API は、access_token に基づいてレート制限できます。

基本的に、最初のリクエストが実際の iOS デバイスからのものであることを確認するという面倒な作業はすべて Apple に任せます。

これをデスクトップ クライアントに拡張することは可能ですが、UX が多少損なわれます。ステップ 1 を変更/access_token/createして、任意のリクエストを受け入れるようにします。リクエストが iOS デバイスからのものでない場合は、access_token を発行する前に、ユーザーにメール アドレスの確認やキャプチャなどの解決を強制します。

Android デバイス (よく知られていない) には、同様のプッシュ通知メカニズムがあり、その場合はそれを使用できますが、プッシュ通知メカニズムがない場合は、Android ユーザーに上記の不都合をもたらす可能性があります。

于 2012-08-22T19:30:59.830 に答える
12

このアイデアについては、SPAM問題のグローバルな解決策を見つけることについて話しているときに聞いたことがあります。つまり、クライアントに時間のかかる計算を実行させることです。

正確に言うと、一瞬のうちにいくつかzを計算できる計算アルゴリズムを見つけてください。ただし、与えられたものだけを計算するにはかなりの時間がかかります。実際のアルゴリズムを提供することはできませんが、この基準をはるかに超えるアルゴリズムはたくさんあると確信しています。xyzx

これで、手順全体が次のようになります。

  1. 最初のクライアント要求時に、いくつかsession_idを生成し、このためにとsession_idのペアを生成します。xy
  2. クライアントにとを提供しsession_idますx
  3. クライアントは、データを受信するとすぐに計算を開始できます(ユーザーの操作に関係のない一部のバックグラウンドスレッドで)。
  4. マーカーをリクエストするには、クライアントが提供session_idして計算する必要がありますz
  5. クライアントzが大丈夫かどうかをすばやく確認できます。すでに持っているのでxy簡単に行うことができます。
  6. (オプション1)各session_id店舗について、要求されている量/頻度。あなたがそれが乱用されていると疑う瞬間-力の再生xy
  7. (オプション2)新規xを強制yし、連続するリクエストごとにsession_id

6と7のどちらを選択するかは、実際には、アルゴリズムの複雑さとマーカーデータベースの予想される「フェアユース」の使用に応じて調整されます。見積もりが良ければ、悪意のあるクライアントが大量のデータを取得したり、サーバーに過負荷をかけたりすることはありません。

それが役に立てば幸い。

于 2012-08-17T16:32:58.977 に答える
6

クライアント側で実際にできることは何もありません。アプリ全体 (キーやその他の保護メカニズムを含む) をユーザーに提供する必要があります。悪意のあるユーザーが Web サービスにいたずらをしたい場合、リバース エンジニアリングを行って Web サービスにアクセスする必要があります。これを難しくすることはできますが、どんなに頑張ってもこれを防ぐことはできません。

サーバー側のレート制限 (IP アドレスごと) を実装するだけで、これについてはもう心配する必要はありません。これは勝てない戦いです。誰かが本当にあなたのサーバーに損害を与えたい場合、Web サービス プロトコルについて何も知らなくても、DDOS を実行できます。

また、最初の接続時にユーザーごとに一意のキーまたは証明書を自動的に生成しても、まったく役に立ちません。攻撃者があなたのプロトコルをリバース エンジニアリングした後、攻撃者はこれらすべてを処理する方法を知っており、あなたのルールに従う必要はありません。レート制限に遭遇するたびに、サーバーから新しいキーを要求することを止めるものは何もありません。

Kuba Wyrostek が説明したアプローチは機能する可能性があります。クライアントに時間のかかる計算を実行させて、リクエストの処理を許可する前にすばやく確認できます。ただし、これに時間がかかりすぎることはありません。そうしないと、ユーザーはバッテリ寿命の短縮について不満を言うでしょう。また、攻撃者は、別の iPhone ではなく、より強力なデスクトップ ハードウェアを使用する可能性があります。

最後に、これが本当に必要だと思いますか? ユーザーが登録する必要がないようにするため、データやサービスはあまり重要ではありません。では、アプリをリバース エンジニアリングし、サーバーに大量のリクエストを送信することで、何を得る必要があるのでしょうか?

于 2012-08-19T20:06:34.200 に答える
3

私は実際に、これらのアイデアのいくつかを実装する理由を探していました。これまでのところ素晴らしい質問と回答。

@Kuba Wyrostek がスパム問題のように扱うことは解決策の一部であることに同意します。特に、アプリにテキスト メッセージ (ストア、サービス、またはメッセージを追加する) がある場合、アプリにスパムを送信する一般的な理由は何かを宣伝することであることに気付くかもしれません。それが私の最初の推奨事項につながります。

1) 各メッセージの有効性を 0% から 100% の有効なパーセンテージとして扱います。サーバー側でヒューレスティクスを使用してプロセスを開発し、メッセージが多かれ少なかれ有効であるとマークします。これにより、追加のメソッド (クライアントに複雑な値の計算を強制するなど) の一部を、それが必要な要求のみに向けることができます。また、悪用の可能性をより簡単に記録して確認することもできます (また、標的にされた後、その悪用をより簡単に一掃できます)。

しかし、あなたのアプリは、スパム戦争において電子メール サーバーよりも強力なアドバンテージを持っています。会話の両側を制御するのはあなたです。この状況は、実際に役立つと思われる他の 2 つの関連する状況を思い起こさせます。それは、衛星有料テレビの「戦争」と、インスタント メッセンジャーのクローンの「戦争」です。(たとえば、 Black Sunday ハックに関する Jeff Atwoods の投稿を参照してください)。これらのスタンドオフから、いたちごっこのゲームを少し先取りするのに役立ついくつかのアイデアを次に示します。

2) クライアントに余分なデータを送信するように要求します- リクエストに関するデータは理にかなっています。iOS では、場所の精度指標を送信します。Android では、エフェメリス情報などの生の GPS データを実際に取得できます。その後 (すぐにではなく、後で)、このデータの有効性のチェックを開始できます。これにより、誰かがリクエストをリバースエンジニアリングすることを余儀なくされます。たとえば、彼らがGPS衛星を視界に送っている場合、それを公に知られているデータと照合して確認することができます.

3) 敵をモバイル デバイスに強制する- @Sven が指摘しているように、攻撃者はデスクトップ PC を使用する可能性があります。彼らにこれをさせないでください(または少なくとも彼らをもっと一生懸命働かせてください). たとえば、クライアントに数学関数 (サーバーから送信される) を計算させ、電話モデルに基づいて、完了するのに正しいミリ秒数がかかるかどうかを確認できます。または、サーバーからのデータを使用して、ハードウェア クリッピング動作に依存する小さな 3D レンダリング タスクを実行します。結果をハッシュして送り返します。これらはすべて範囲内です。これはマルチタスク OS です。しかし、それは非常に役立ちます。

4) それらを動的にする- クライアントのコンテキストで計算する必要があるアルゴリズムのビットを送信します。Apple は、リモート コードが解釈されることについて少しおかしくなっていますが、ユーザーにレンダリングしない JavaScript を少し送信するようなことはうまくいくかもしれません。そのコードは、事前に予測するのが難しいあらゆる種類の固有の質問 (画面の解像度、ブラウザーのバージョン、WebKit の癖) を尋ねる可能性があります。彼らが追いつくにつれて、これらでより創造的になることができます.

5) CAPTCHA - ヒューリスティックが疑わしいデータを検出し始めた場合は、認証を強制します。多言語アプリを使用している場合、画像または Unicode 文字を別の文字に一致させるだけの簡単な作業で済みます。後で更新できるようにレンダリングします。

とにかく - いくつかの追加のアイデア。幸運を!

于 2012-08-19T23:37:38.693 に答える
2

ここに別の「解決策」があります:

  • この問題に時間を無駄にしないでください。

なぜなら:

  • パブリック インターフェイスを世界に公開しないため、Web サービスの更新とアプリの更新を介して、いつでも自由に Web サービス インターフェイスを変更できます。
  • このアプリは(あなたが呼んだように)「非常に些細な」ものであり、おそらく現時点ではあまり使用されていません
  • あなたはおそらく今もっとやるべきことがあり、ただ時間を浪費しているだけです

疑わしいパフォーマンスまたはクエリのスパイクがある場合は、最も時間がかからないソリューションを選択します。

  • アプリに保存されたパスワード (clientid) を導入します (これらのユーザーの 95% をブロックします)。この clientid は、後で他のプログラマーがサービスに合法的にアクセスしたい場合に、さまざまなクライアントを識別するために使用できます。
  • レート制限を導入する (前述のとおり)

これにより、99.99% の問題が解決され、すぐに作業を開始して素晴らしい新機能を作成できます。

于 2012-08-23T08:12:07.827 に答える
1

注意が必要です。誰もデータを改ざんすることを期待していないので、あなたの懸念は完全性ではありません。また、クライアントのリストを維持していないため、信頼性について懸念する必要はありませんか?

また、よく知られているすべての Web サービス攻撃 (DoS 攻撃やリプレイ攻撃など) に対しては、それらを防止できるファイアウォールを利用できます。ですから、あまり気にする必要はないと思います。

しかし、プレーン テキスト データを送信するのではなく、ダウンロード アプリがデータをプッシュしていることを確認したい場合があります。

評価しているアプローチを見ると:

セキュリティで保護されたキー: サーバーとアプリが同じキーを共有することを理解しています。正しければ、すべてのデバイス上のすべてのアプリが同じキーを共有します。アプリがデータをプッシュすると、実際のフィードがハッシュされ、実際のフィードとハッシュされたフィード全体で送信されます。サーバー側では、キーを使用して実際のフィードをハッシュし、ハッシュされたフィードと一致するかどうかを確認します。そして、私の意見では、このソリューションは主に、あなたにとって大きな懸念事項ではないデータの整合性の側面に対処しています. 右!(もちろん、リバース エンジニアリングはおそらく簡単です。)

上記のアプローチでは、サーバーはキーを保存する必要があるため、キーが侵害された場合、サービス全体が破損し、すべてのアプリを新しいキーで更新することが難しくなります。または、アプリがキーを生成する場合は、ダイジェストまたは何か (タイムスタンプ + 乱数など) としてメッセージと共にキーを送信する必要があります。壊すのはそれほど難しくありません。

証明書:証明書を使用しても同じセキュリティが得られます..しかし、破ることは困難ですが、スチールするのは簡単です:)。デバイスで秘密鍵を保持している場合 (もちろん、サーバーで公開鍵を保持する必要があります)。クライアントごとに秘密鍵を割り当てる必要があり、サーバーは割り当てられたすべての秘密鍵の公開鍵を維持する必要があります。秘密鍵が危険にさらされた場合、その 1 つのアプリだけが赤旗を掲げて更新を要求できます。

したがって、残っているのは、アプリケーション開発の観点から、偽造されたデータを避けたいということです。イタズラ防止のために そんなことをチェックするのはアプリのロジックだけです。最後の 10 個 (または最適な数でさえ) のフィード (同じ IP からの) をキャッシュし、欠陥があるかどうかを何らかのロジックで検証する必要があります。

于 2012-08-12T16:30:39.910 に答える
1

レート制限 + クライアントの「ソフト」登録を使用できます。

基本的に、最初のリクエスト時にユーザーのデフォルトに保存できるデバイス ID を生成します。リクエストごとに、サーバーに送信されたリクエストの数を追跡し、サーバー側で制限します。これは非常に迅速に達成できます。

生成されたデバイス ID + post/get パラメーターを使用してリクエストに署名するために、ある種の共有シークレットを使用することもできます。

于 2012-08-17T17:17:50.287 に答える