web-dev-qa-db-ja.com

RESTfulサービスでのPOST / GETリクエストのスプーフィング

認証とデータのためにRESTfulサービスに接続するアプリの開発を始めました。ユーザーは、ユーザー名とパスワードを/ tokenエンドポイントにPOSTします。ログインに成功すると、ベアラトークンを取得し、それを保護された別のリソースへの後続の呼び出しでAuthorizationヘッダーに追加します。

私の質問は、ユーザーがアプリからの通常の投稿を傍受(トークンを取得)し、POST要求の束を(ポストマンまたはフィドラーのようなものを使用して)送信して、偽の投稿や記事、その他アプリが行うこと。

これから保護するいくつかの可能な方法は何ですか?サービスへのトラフィックが最終的にTLSを経由するという事実により、これは問題になりませんか?

13
ska-dev

私の質問は、ユーザーがアプリから通常の投稿をインターセプトし(トークンを取得)、次にPOSTリクエストの束を送信(ポストマンやフィドラーのようなものを使用))して、大量の偽の投稿や記事、その他アプリが行うこと。

何もない

サービスへのトラフィックが最終的にTLSを経由するという事実により、これは問題になりませんか?

これはまったく違いがありません。

これから保護するいくつかの可能な方法は何ですか?

最も一般的なのはレート制限です。つまり誰かが予想よりはるかに高いレベルで投稿した場合、その投稿を拒否します。これにはいくつかのアプローチがあります-彼らが最後に投稿したのはいつか、N分間のローリング平均などです。誤検出が発生してユーザーが投稿コンテンツを失うことを望まない場合は、続行するために再認証してください。

別のアプローチはキャプチャです。つまり、ユーザーが人間であることをユーザーに証明させようとしています。

もう1つは、スパムフィルターまたはAIを使用して自動的に生成されたコンテンツを検出しようとするものです。

29
Hector

私の質問は、ユーザーがアプリからの通常の投稿を傍受できないようにするものです

何もない。

サービスへのトラフィックが最終的にTLSを経由するという事実により、これは問題になりませんか?

モバイルプラットフォーム(Android/iOS)用に作成すると、その作業は非常に難しくなります(不可能ではありません)。

あなたがブラウザのためにそれを作るなら、これは多くの保護を追加しません。

これから保護するいくつかの可能な方法は何ですか?

自動リクエストから保護するのは難しいですが、実行できることの1つはレート制限です。

12
Ruben_NL

私の質問は、ユーザーがアプリからの通常の投稿を傍受(トークンを取得)し、POST要求の束を(ポストマンまたはフィドラーのようなものを使用して)送信して多数の偽の投稿や記事、その他アプリが行うこと。

これから保護するいくつかの可能な方法は何ですか?

あなたはしません。つまり、あなたはthis-に対して保護しません。認証と承認の観点から、ここでは攻撃は発生せず、完全に正当なトラフィックのみです。

代わりに問題は、「ユーザーが自分のサービスをスパムしないようにするにはどうすればよいですか?」です。 (または同様)、それは認証トークンの質問と完全に直交です。ユーザーは、アプリを介して手動で同様にスパムを送信することができます。

ユーザーアカウントによるレート制限、IPアドレスによるレート制限、Cookieまたはデバイス識別子を使用した複数のアカウントの結合によるデバイスによるレート制限、ブラックリストの条件、スパムのヒューリスティックなどはすべて、スパムに対処する一般的な方法です。しかし、実際のthingは何を防止しようとしているのか、それは調査する必要があることであり、ユーザーがクライアント側で変更することを防止するものではありません(ユーザーはいつでも実行できます)。

クライアントに提供するトークンには、サーバー側で検証される署名済みの有効期限が含まれている必要があります(たとえば、アプリで予想される一般的なユーザーセッション時間に制限されています)。これにより、再投稿が妨げられることはありませんが、認証後に実行できる期間が制限されます。有効期限が切れると、ユーザーは再認証する必要があります。これは一般的に JSON Web Token を使用して実装されます。

ただし、あなたは正当なユーザーによる悪意のある悪用について話しています(攻撃者が既に正当なユーザーのデバイスを侵害し、トラフィックを平文で傍受できる場合を除きます)。他の人は指摘しました(たとえば、すべての要求でユーザーを認証させることによって)。資格情報をデバイスに保存し、それらを警告なしに再送信することは非常に重要です。

4
Sasha K

正解です。セッショントークンだけでは、ハッカーがパケットを傍受して自分の目的でトークンを再利用できないことは保証されません。少なくともトークンが有効である限り。ほとんどのセッショントークンには時間制限がありますが、それはサーバーエンドでトークンを検証するために使用される認証方法に依存します。

タイミングはこれを防ぐ1つの方法ですが、絶対確実というわけではありません。アプリを作成しているので、アプリの操作速度と予想されるサービス呼び出し率についての合理的な考えが必要です。アプリが通常の使用で1秒に1回以上サービスコールを送信できず、サービスが1秒間に100リクエストを受信する場合、それは明らかにハッカーの仕事です。

ただし、これはハッカーがサービスをリクエストで攻撃することを前提としています。ハッカーは、いくつかの失敗の後でそれを理解し、リクエストの割合を下げることができます。サービスが有効なセッショントークンであると信じるものを拒否するのを見るとすぐに、タイミングなどの明白なものを見始めます。

これを防ぐ別の方法は、サービスにアクセスするためにSSLを要求することです。これにより、パケットと認証トークンの抽出が困難になります。パケットスニファよりも多くのものが必要になります。特に知識豊富なハッカーは、アプリのバイナリを調べようとするかもしれませんが、特にモバイルプラットフォームでは、これは多くの作業です。サーバー用のSSL証明書を購入する必要がありますが、それは安価な保険です。

私が実験してきた方法は、シーケンス番号をセッショントークンに追加し、ハッシュしてシーケンス番号のように見えないようにすることです。許可サービスは、トークンが検証されるたびに増分されるカウントを維持します。トークンを検証する前にシーケンスバイトを取り除き、シーケンス番号をチェックします。

クライアントは、最初にセッショントークンを受け取ったときにゼロから始まり、呼び出しが行われるたびに追加されたカウントを1ずつ増やすことが期待されています。したがって、サーバーが最後にシーケンス250を受信し、別のシーケンスがそのシーケンス135になったら、要求を無視し、ソースIPをロックアウトして、ハッキングの試みが進行中である可能性があることを管理者に通知します。

ただし、これによりクライアントアプリに複雑さが増し、ドロップされたパケットやドロップされたリターンパケットが大量に実行される可能性があります。ちょうど私が実験してきた何か。

そして、はい、ハッカーは最終的にそれを理解できるかもしれませんが、多くの誤った開始後にのみ...侵入の試みが進行中であることを管理者に警告します。

2
tj1000

他の多くの人々は、「何を防ぐのか」についての最初の質問に対して「何もしない」と言っていますが、それは事実です。最終的に、絶対的に決定された誰かを実際に倒すものは何もありません。

また、これに対抗できる戦略を求めました。 tj1000はそれに触れ、私がクレジットカード端末で行った作業に基づいて、私は同様のアイデアを争いに投げ込むと思いました。

私がジュニア開発者だった頃、私はプロの開発者に解決する価値がないと思われるタスクを手渡されました(私が支払われたものを示していると思います)。古いpre-isdnリンクを介して呼び出し、認証を行い、トランザクションを記録し、サーバーから次のトランザクションに承認または拒否する何千ものクレジットカード端末がありました。私たちが承認した後にトランザクションが無効になった場合、これはターミナルからのメッセージのフォローアップがまったくなかったことはかわいいです(これは、ユーザーIDがチップとピンによって事前認証される前の署名の時代でした)が、する必要はありません

これらのトランザクションは、MAC-メッセージ認証コードと呼ばれるものによって保護および確認されました。端末のハードウェアに組み込まれたのは、製造元によって端末ごとに固有のハッシュキーでした。製造業者は、ハッシュキーが何であるかを私たちと共有し、端末がその一意のIDを提示して現れたときに、ハッシュキーを検索することができます。端末によって形成されたメッセージバイトは、端末によってハッシュされ、以前または最初のハッシュの半分がメッセージに追加されます。残りの半分は、次のメッセージに使用されるハッシュキーを更新するために使用されます。サーバー側では、メッセージが改ざんされていないかどうかを確認するために同じハッシュを実行し、同じハッシュ結果が得られます。また、ハッシュキーを同じ半分の剰余でロールすることも知っています。以前のハッシュキーも追跡します。次回メッセージが届いたとき、2つのうちの1つが事実でした。前のトランザクションが成功し、日次合計に累積される場合、端末はその新しいロールされたハッシュキーを使用して最新のメッセージをハッシュします。以前のトランザクションがロールバックされた場合(ユーザーがキャンセルした、署名が不正など)、端末は以前のハッシュキーを再利用していました。最新のロールされたキーを使用してメッセージをハッシュし、一致を見つけることなく、以前のキーを使用してハッシュし、一致を見つけることにより、以前のトランザクションの運命が失敗したことを認識し、それを毎日の合計から削除しました。

ハッシュキーは時々同期しなくなります。これが発生した場合、保存されているキーのどちらもメッセージに一致するハッシュを生成しません。試すべきもう1つのキーがあります-初期キー(スーパーバイザーユーザーはキーを初期にリセットできますが、一部のユーザーは、問題が発生したときにこれを再起動のようなものだと信じていました-ほとんどの場合、それよりも多くの問題を引き起こしました)解決しました。最初のキーが機能した場合、以前のトランザクションで何が起こったのか確かなことは言えませんが、通常、人々は返済されなかった場合に返済されなかった場合に不平を言い、そうでない場合は不平を言うという理論に基づいてそれらを蓄積しました(請求された人々のアカウント)彼らが買ったものは払い戻されました。

最初のキーが機能しなかった場合、キーのローリング同期が失われるとそれ以上メッセージが機能しなくなるため、端末は事実上役に立たなくなります。端末にキー自体をリセットするように指示する権限はありませんでしたが、ユーザーにそうするように促すメッセージをディスプレイに表示することができました

要するに、トークンが取得され、保存されているパスワードの代替として再生されることが心配な場合は、同じトークンを使用する必要はありません。他の人たちは、トークンを一定期間後に期限切れにするオプションを指摘しました。この方法は、基本的に、各要求の後にトークンを期限切れにする(トークンに連続番号を追加することについての別の言及と同様)とともに、ステップで実行する必要がある各サイドで新しいトークンを計算する既知の内部方法を使用します。

クレジットカードの世界が英国で行う方法の退屈な詳細に興味がある場合は、APACS 70 Standard Book 2およびBook 5を参照してください。これらは、残念ながら無料で入手できません。受け取るには、メンバーである必要があります新しい出版物のコピーですが、古いバージョンのコンテンツがウェブ上に浮かんでいる場合があります

1
Caius Jard

したがって、クライアントマシンを保護して、トークンをクライアント側で保護する方法はありませんが、JWTのセキュリティにはいくつかのベストプラクティスがあります。

  1. 更新トークンを実装し、有効期間の短いアクセストークンを発行します。これにより、あらゆる攻撃が複雑になります。更新トークンが実装されているのは、SQLテーブルを使用して確認できる方法です(インスタントブートなど)。

  2. ログアウト時にクライアントからトークンを削除します(これは明らかです)。

  3. トークンを暗号化することはできますが、暗号化を元に戻すことができるため、再び困難になります。

  4. 秘密鍵を使用してトークンに署名し、必要に応じてローテーションします(例:リリースごと)。秘密鍵を変更すると、それ以前のすべてのトークンが無効になります。

また、以下をお読みください: https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

さらにセキュリティが必要な場合は、クライアントを具体的に保護するためのより多くのメカニズムが必要です。ユーザーIPをホワイトリストに登録し、ユーザーにAVやフィッシング対策のトレーニングを確実に受けさせるなどです。

1
RandomUs1r

TL; DR妥当なスパムレートに満足している熟練したユーザーは、他の方法ではない場合でも、スパムを手動で入力することで通過します


アプリに各リクエストを個別に認証させます。それは間違いなく絶対確実ではありません、そしてそれはトラフィックの増加をもたらしますが、それは実行可能です。

1つの方法:メッセージ投稿は単一の投稿ではなく、GETの後にPOSTが続きます。 GETはnonce(現在のタイムスタンプである可能性があります)を提供し、POSTはnonceを、例えばアプリケーションシークレットでソルトされたnonceのMD5などと一緒に提供する必要があります。もちろん、発行されたナンスを保存して、リプレイ攻撃を回避します。

ログイン時にセッションnonceを指定して、それをセッション全体で使用することもできます(もちろん、ユーザーはそれをインターセプトして、2つ目のスパミングアプリにコピーすることができます。ただし、これは認証Cookieからの大きな改善ではありません。

または、現在のタイムスタンプと、アプリのシークレットでソルトされた前記タイムスタンプのハッシュの形式で、すべてのアプリリクエストに検証をサイレントに追加できます。次に、同じ2番目のクライアント側で2つの投稿を防ぐことで、一意性を保証できます。

次に、サーバーはタイムスタンプがnow()からそれほど遠くないこと、およびハッシュが一致することを確認します。サーバーがブルートフォースで許容できる場合は、タイムスタンプを省略できます(timestamp = now()-60からnow()+ 60の場合、if hash(secret + timestamp)...)。

ユーザーはアプリの秘密をハッキングする必要があります。これは、ネットワークトラフィックを傍受するだけでは困難です。文字列/データがアプリで簡単に認識できる場合は、タイムスタンプを送信することにより、あいまいな情報を介してlittleセキュリティを追加し、シークレットとタイムスタンプのハッシュを送信できます。 7秒前1。これにより、ユーザーはアプリ全体をリバースエンジニアリングする必要があります。


(1) プログラムで1から32バイトまでのすべてのシーケンスをテストし、タイムスタンプに16進数、2進数、10進数で付加および接尾辞を付けて、区切り記号なしを含む一連の区切り記号を付け、結果が挑戦への対応。これは私にバイナリをデバッグすることをできないことを可能にしました、そしてそれは私が行うことができなかったでしょう、そしてセットアップするのに20分かかりました、そして2つ実行します。タイムスタンプが既知の定数を追加することによって難読化されていたとしたら、私は成功しなかっただろう。定数が大きければ、トリックを知っていても実用的ではありません。

1
LSerni

他の人が触れたように、コードがユーザーのデバイスで実行されると、基本的にあなたができることは何もありません。ブラウザで実行されている場合、トークンプロセスのリバースエンジニアリングは簡単です。アプリで実行している場合、リバースエンジニアリングをより困難にすることができますが、それでも可能です。

モバイルアプリの場合、攻撃者には2つのオプションがあります。

1)プロトコルをリバースエンジニアリングします。最も簡単な方法は、ネットワークトラフィックをスニッフィングすることです。それを困難にするために導入できる難読化(証明書のピン留め、MAC +秘密鍵+ローテーション)がありますが、最終的に攻撃者はそれらを突破します。ただし、証明書のピン留めや秘密鍵によるアプローチを使用している場合、攻撃者はパケットを単純に傍受してプロトコルをリバースエンジニアリングすることはできません。証明書のピン留めを無効にしたり、メモリ内の秘密鍵を見つけたりするには、バイナリを逆コンパイルする必要があります。

2)アプリケーションをブラックボックスとして扱い、それとの相互作用を自動化します。これは、物理デバイスのファームで実行できます(脱獄iOS /ルート化されている場合ははるかに簡単です) Android)、またはエミュレーターのファームを使用します。攻撃者の観点から見ると、これは、プッシュした更新に対して回復力があるため、より信頼性の高いアプローチになる可能性があります。

#1(バイナリの逆コンパイル)から保護するには、多くのオプションがありますが、それらはすべて、リバースエンジニアリングの難易度を上げることであり、完全に防ぐことはできません。ぶら下がりの実は、バイナリの難読化とデバッガーの検出です。難読化の場合は、シンボルテーブルを難読化したり、平凡な関数で暗号化ロジックを非表示にしたり(またはアセンブリに直接書き込む)できます。デバッガーの検出には、デバッガーが実行されているかどうかを判別するためのさまざまな手法があります。捕まえた場合、アプリをクラッシュさせたり、攻撃者と一緒にゲームをプレイしたりできます。

#2(エミュレーター/デバイスファーム)からの保護は少し難しいですが、繰り返しになりますが、攻撃者の仕事をより困難にすることができます。 1つのオプションは、デバイスがジェイルブレイクされているかどうかをチェックし(これは#1からも防御します)、そうであればアプリをクラッシュさせることです。 Android少なくとも、Googleの 証明サービス を使用する別のオプションです。これにより、物理ファームではなく、エミュレータファームのシナリオが回避されます。iOSの場合、AppleはiOS11で同様の deviceCheck API をリリースしましたが、範囲ははるかに制限されています。

この例を実際に使用したい場合は、これらの機能の多くを実装したSnapchat.appをチェックアウトしてください。

1
formicophobia

アプリが(ユーザー名/パスワード)を一度認証し、RESTサービス認証にトークンシステムを使用するように設計されている場合、そのアプリは独自のバックドアアクセスを効果的に作成しています。

このソリューションは私を混乱させると確信していますが、基本的にはすべての単一のRESTfulエンドポイントで認証する必要があります。

RESTリクエストのたびにユーザーを困らせてパスワードを要求するように選択できますが、これによりアプリが失敗する傾向があります。

他のオプションは、ログイン時にユーザーの認証情報をアプリのメモリに保存し、認証情報をサイレントにRESTエンドポイントに送信することです。

0
MonkeyZeus