独自のレート制限APIをドッグフーディングする


117

概要:

私の会社はレート制限されたAPIを開発しました。私たちの目標は2つあります。

  • A:製品の周りに強力な開発者エコシステムを作成します。
  • B:APIを使用して独自のアプリケーションを駆動することにより、APIの能力を実証します。

明確化:なぜレート制限を行うのか?

APIは、製品への追加として販売するため、レート制限を行っています。APIへの匿名アクセスでは、1時間あたりのAPI呼び出しのしきい値が非常に低くなっていますが、有料のお客様は1時間あたり1000以上の呼び出しを許可されています。

問題:

私たちのレート制限APIは、開発者のエコシステムに最適ですが、ドッグフードを行うために、同じレート制限に制限することはできません。APIのフロントエンドはすべてJavaScriptであり、APIへの直接のAjax呼び出しを行います。

だから問題は:

どのようにAPIを保護して、レート制限を削除できるようにしますか?

探索されたソリューション(およびそれらが機能しなかった理由)

  1. ホストヘッダーに対してリファラーを確認します。- リファラーが簡単に偽造されるため、欠陥があります

  2. HMACを使用して、要求と共有秘密に基づいた署名を作成し、サーバーで要求を確認します。- シークレットとアルゴリズムは、フロントエンドのJavaScriptを調べれば簡単に判断できるため、問題が発生します。

  3. リクエストをプロキシし、プロキシでリクエストに署名する- プロキシ自体がAPIを公開しているため、まだ欠陥があります。

質問:

Stack Overflowの優れた頭脳に代替ソリューションを提示することを期待しています。この問題をどのように解決しますか?


13
できません。レート制限に制限したくない独自のAPIの使用がパブリックWebページからのものである場合、すでに知っているように、これらのパブリックWebページから安全なことはできません。公開ウェブページには秘密はありません。だから、あなたがあなたのウェブページでできること、そして他の誰でもできること。
jfriend00 2016年

28
実際にドッグフードの使用で解決するレート制限の問題があると思いますか?サイトとWebページを使用する各ユーザーは、レート制限コードとはまったく異なるユーザーのように見える必要があります。したがって、各Webページが通常のレート制限ルールに従っていることを確認してください。問題はありません。レート制限がクライアントごとであると仮定すると、1人のユーザーは他のユーザーとは何の関係もありません。
jfriend00 2016年

6
ユーザーごと、ロールごと、権限ごと、またはアプリケーションのスコープごとにレート制限とスロットルを提供するAPI管理ソリューションを検討してみませんか。例:wso2 api manger
MiddlewareManiac


28
ドッグフーディングでパブリックAPIに重大な問題が発見され(レート制限が低すぎること)、それを修正するのではなく、回避しようとしています。発見した問題を無視するのであれば、なぜドッグフードなのか?
user253751

回答:


93

独自のJavaScriptクライアントがAPIに直接アクセスしているため、同じAPIキーの使用を含め、だれでもそれが何をしているかを模倣して模倣することができます。コードを難読化したり、さまざまなハードルを設定したりするなど、より困難にすることもできますが、あなたと抑制しようとしている人は基本的に同じアクセス権を持っています。権限の違いを作ろうとするのではなく、非公式のクライアントがスコープ内のすべてのアクセスを使用してもまったく問題ないシステムを構築する必要がありますが、システムは、すべてのクライアントで公式に使用されるように配置されています。大きい。

これは多くの場合、アプリケーション全体で1つのトークンを使用するのではなく、ユーザーごとのアクセストークンを使用して行われます。各トークンの制限は、APIの一般的な使用には十分ですが、それを悪用しようとするユーザーには制限があります。たとえば、1分あたり100コールで通常のブラウジングをサポートするには十分すぎるかもしれませんが、私があなたをこすることを望むなら、私はその予算では効果的にそれを行うことができません。

常に武器競争があります-ボットユーザーアカウントをたくさん作成することで、制限を回避できます。ただし、実際の人間に少しの費用をかけて、サインアップフローにキャプチャを追加するだけであれば、これはかなり解決された問題です。これらのシナリオに入ると、すべてが便利さと制限の間のトレードオフにすぎません。あなたは完全に防弾の何かを決して見つけることができないので、それを十分に良くすることに集中し、穴がどこにあったかを知るために誰かがあなたを悪用するまで待つ。


8
これを最良の回答として受け入れます。私たちが決定したルートは、有効期限の短いJWTトークンを使用し、それらの呼び出しのレート制限を増やすことです。トークンにいくつかの追加情報をエンコードして、バックエンドにレートの上限を通知します。これらのトークンはバックエンドで安全に署名されているため、なりすましの問題はありません。誰かがまだトークンを使用できますが、トークンは数日後に期限切れになるため、あらゆる種類のボットを維持することは難しくなります。
Jason Waldrip、2016年

33

これが問題の原因である場合は、開発者の推定エコシステムに問題が発生します(たとえば、別のUIを開発しようとした場合)。実際に自分のドッグフードを食べている場合は、アプリケーションでAPI(およびレート制限)が機能するようにします。ここにいくつかの提案があります:

  • IPアドレスによるレート制限を行わないでください。むしろ、ユーザーに関連付けられたもの、たとえばユーザーIDによるレート制限。認証段階でレート制限を適用します。

  • ユーザーがAPIを継続的に呼び出す必要がないようにAPIを設計します(たとえば、毎回1つのアイテムを返す繰り返し呼び出しではなく、多くの結果を返すリスト呼び出しを与える)

  • 開発者のエコシステムに期待するのと同じ制約でWebアプリを設計します。つまり、合理的なスロットル率内で設計できるようにします。

  • バックエンドがスケーラブル(水平方向が望ましい)であることを確認してください。そうすれば、実際にUIに問題を引き起こすほど低いレベルでスロットルを強制する必要がなくなります。

  • あなたのスロットリングがバーストに対処する能力を持っていることを確認するだけでなく、長期間の乱用を制限してください。

  • スロットリングが、削除しようとしている乱用に合わせた賢明なアクションを実行することを確認してください。たとえば、接続を拒否するのではなく、軽度の乱用者をキューに入れるか遅延させることを検討してください。ほとんどのWebフロントエンドは、一度に4つの同時接続のみを開きます。5分の1を開こうとする試みを遅らせると、Webクライアント(2つのWebクライアント)と同時にCLIを使用している場合にのみヒットします。n番目のAPI呼び出しを失敗するのではなく、間隔を空けずに遅らせると、エンドユーザーは中断するのではなく速度が低下するのを目にします。これを同時にキューイングするN API呼び出しのみと組み合わせると、多数のAPI呼び出しを並列化しているユーザーのみにヒットします。これは、おそらく望ましい動作ではありません。 1時間で100を超える順次API呼び出しよりも悪い。

これはあなたの質問に答えませんでしたか?まあ、本当に求めていることを行う必要がある場合は、認証段階でレート制限を行い、ユーザーが属するグループに基づいて異なるレート制限を適用します。(開発者とQAチームが使用する)1組の認証情報を使用している場合は、レート制限が高くなります。しかし、これがなぜ開発者やQAチームが認識していない問題を見てエコシステムに必然的につながるのか、すぐにわかります。


11

製品を購入します。自分の有料顧客になります。

「私たちのAPIへの匿名アクセスは、1時間あたりのAPI呼び出しのしきい値が非常に低くなっていますが、有料のお客様は1時間あたり1000以上の呼び出しを許可されています。」

これは、顧客の視点からシステムをテストするのにも役立ちます。


1
明白な答え。ここでは不正行為や偽造はありません!
wizzwizz4 2016年

9

残念ながら、これに対する完全な解決策はありません。

一般的なアプローチは、通常、なりすましを提供することですクライアントが自身を識別する方法(たとえば、識別子、バージョン、APIキーなど)、クライアントがアクセス制限に使用できる自身に関する情報を登録する方法(たとえば、クライアントは特定のIPアドレス範囲内のサーバーである)したがって、その範囲の呼び出し元のみを許可します。たとえば、クライアントはJavaScriptですが、ブラウザの特定のカテゴリにのみ配信されるため、特定のユーザーエージェント文字列を指定するHTTPリクエストへのアクセスのみを許可します。その後、機械学習/パターンを使用します。スプーフィングされたクライアントである可能性が高い異常な使用法を検出し、これらのスプーフィングされたクライアントからのトラフィックを拒否する(または、これらの使用法が確かに正当なクライアントからのものではないことをクライアントに確認し、スプーフィング可能な資格情報を置き換えてから、古いものを使用してそれ以上のトラフィックを許可しない偽装された資格情報)。

キーの複数のレイヤーを使用することにより、なりすましを少し難しくすることができます。たとえば、サーバー(およびIPアドレス範囲の限定されたセットでのみ使用できる)に存在するより長期間有効な認証情報を提供して、クライアント(ユーザーエージェントなど)に関する情報を記録するAPI呼び出しを実行します。クライアント側のAPIリクエスト用にクライアントで使用するためにJavaScriptでシンジケートされた、有効期間が短いクライアント側のキーを返します。これも不完全です(スプーファーが資格情報を取得するために同じサーバー呼び出しを発行する可能性があります)が、返されたAPIキーが難読化された(そして頻繁に変更される)JavaScriptまたはHTMLに含まれている場合は困難になります応答から確実に抽出するため)。これは、なりすましをより簡単に検出する方法も提供します。クライアント側のキーは、特定のクライアント(例:


8

問題のアプリが公開されている必要があると仮定すると、あまり選択肢がありません。

APIの能力を実証する別の方法を選択してください。たとえば、そのようなアプリを作成してそのソースを共有しますが、実際にはそのコードを実行しないでください。ただし、それが十分に文書化されていることを確認してください。そうすれば、誰でもそれを展開して、機能することを確認できます(スロットルが適用される場合があります)。

実行するアプリは、クライアント側のAPIリクエストを回避し、よりサーバーにレンダリングされるようにリファクタリングする必要があります。APIをドッグフードすることはできますが、明確な方法ではありません。サーバー側からスロットルのないAPIに安全なリクエストを送信してください。

レート制限調整して、アプリが機能し、パフォーマンスの最適化に投資して負荷を処理できるようにします。

そして、ええ、そもそもコアAPIをスロットルフリーにして、それをプライベートネットワーク内に保持してください。公開されている別のレイヤーでスロットルします。


4

UIとスロットルフリーAPIの個別のインスタンスを立ち上げ、組織からのIPアドレスへのアクセスを制限できますか?

たとえば、すべてを企業のファイアウォールの背後に配置し、インスタンス間でデータを共有する必要がある場合は、アプリケーションをパブリックインスタンスと同じデータベースに接続します。


4

特定のIPアドレス/ユーザーにバインドされ、存続時間が制限されている一意のセッションIDを生成しようとすることができます。ユーザーがアプリケーションのフロントエンドJavaScriptコードをダウンロードすると、生成されたセッションIDがJavaScriptソースコードに挿入されます。セッションIDは、APIへのすべてのリクエストに添付され、レート制限が解除されます。

IDは単一のIPアドレス、ユーザー、および限られた時間に対してのみ有効であるため、なりすましのために単純にコピーすることはできません。そのため、攻撃者はページを呼び出し、JavaScriptソースからキーを除外するか、新しいユーザーが使用するたびにAjaxリクエストをインターセプトする必要があります。

別のオプション:

独自のアプリケーションのプロキシを設定し、難読化を使用します。プロキシーへのAjax要求は、実際のAPI呼び出しとは異なる名前を使用し、プロキシーはそれらを変換して戻します。そのため、アプリケーションはgetDocument実際のAPIを呼び出さずgetFELSUFDSKJE、プロキシを呼び出します。プロキシは、この呼び出しをgetDocumentに変換し直して、実際のレート制限APIに転送します。

実際のAPIは、プロキシによるリクエストをレート制限しません。

そして、他の人が自分のアプリケーションにプロキシを使用しないように、難読化スキームを毎日変更します。難読化された呼び出し名は、JavaScriptソースコードで自動的に生成され、プロキシで設定されます。

これを使用したいクライアントも、プロキシを使用するために、変化する難読化に対応する必要があります。また、ロギングにリファラーヘッダーなどを使用できるため、プロキシを使用しているユーザーを見つけることができます。または、難読化スキームを変更するときにそれらをキャッチします。


3
  • ソースIPアドレスのホワイトリスト
  • VPN、ホワイトリストVPNメンバーを使用する
  • HTTPヘッダーを追加するプロキシソリューションまたはブラウザアドオンは、プロキシを保護でき、トラフィックを盗聴するMITM攻撃を心配しない場合は問題ありません。
  • シークレットに関するあらゆる解決策は、シークレットを毎日ローテーションすることにより、リークの影響を軽減することができます

これらのソリューションは、フロントエンドWebクライアントには適用されません。APIへのアクセスがバックエンドで行われた場合に最適です。
Jason Waldrip、2016年

@jasonそれらはすべてフロントエンドに適用できます
the8472

2

複数のアカウントをセットアップし、リクエストごとにランダムに1つを選択するか、1時間ごとに使用するアカウントを変更します。このようにして、nアカウントに負荷を分散し、最大でn倍の制限を設定できます。

顧客が許可されていない場合に、これを実行している他のユーザーを見つけようとする場合は、誤って自分をシャットダウンすることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.