レート制限のベストプラクティス
以下のセクションでは、一般的なユースケースにおける典型的なレート制限の設定について説明します。 提供された例示ルールを組み合わせて、ご自身のシナリオに合わせて調整することができます。
レート制限の主なユースケースは以下の通りです:
- リソースに対するきめ細かいアクセス制御を実施し、これにはユーザーエージェント、IPアドレス、リファラー、ホスト、国、地域などの基準に基づくアクセス制御が含まれる。
- クレデンシャルスタッフィングおよびアカウント乗っ取り攻撃から保護します。
- 個々のクライアントが実行する操作の数を制限する。 ボットによるスクレイピングの防止、機密データへのアクセス、新規アカウントの一括作成、およびeコマースプラットフォームにおけるプログラムによる購入が含まれます。
- REST APIをリソース枯渇(標的型 DDoS 攻撃)から保護し、リソース全般の悪用を防ぐ。
- サーバーの過負荷を防止し、操作数を制限することでAPIを GraphQL 保護します。
きめ細かいアクセス制御の実施
レート制限を使用して、ユーザーやアプリケーションがリソースにアクセスする方法を制御できます。 レート制限は、ユーザーエージェント、IPアドレス、リファラー、ホストなどの属性に基づいてトラフィックを制限することで、アプリケーションを悪用から保護するのに役立ちます。
以下の各例は、特定のアクセス制御シナリオ向けにレート制限ルールを設定する方法を示しています。
ユーザーエージェントによるリクエスト制限
特定のユーザーエージェントに対して許可されるリクエスト数を制限できます。 以下のルール例では、モバイルアプリユーザーが10分ごとに最大100回のリクエストを送信できるようにします。 デスクトップブラウザ向けのレートを制限する別のルールを作成することもできます。
| 設定 | 値 |
|---|---|
| マッチング基準 | ユーザーエージェントは等しい MobileApp |
| 式 | http.user_agent eq "MobileApp" |
| 計数特性 | IP |
| レート(リクエスト/期間) | 10分あたり100リクエスト |
| アクション | 管理対象チャレンジ |
特定のIPアドレスまたはASNを許可する
レート制限ルールから特定のIPアドレスまたは自律システム番号(ASN)を含めるか除外することで、アクセスを制御します。
以下のレート制限ルールの例では、同一IPアドレスからのリクエストを1分あたり最大10件まで許可し、指定 /status されたパスへのリクエスト GET を許可します。ただし、そのIPアドレスが「 IPリスト 」に含まれていない場合に限ります partner_ips。
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /status かつ リクエストメソッドが等しい GET かつ IP送信元アドレスがリストに含まれていない partner_ips |
| 式 | http.request.uri.path eq "/status" and http.request.method eq "GET" and not ip.src in $partner_ips |
| 計数特性 | IP |
| レート(リクエスト/期間) | 1分あたり10リクエスト |
| アクション | 管理対象チャレンジ |
リファラーによるリクエスト制限
リファラーページ(第三者の広告や外部ウェブサイトなど)から発信されるリクエストを制限できます。 このユースケースは、間接的なサービス拒否( DDoS DoS)攻撃のリスクを軽減し、リクエストのクォータ管理を支援します。
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /status および リクエストメソッドが等しい GET |
| 式 | http.request.uri.path eq "/status" and http.request.method eq "GET" |
| 計数特性 | ヘッダー (Referrer)。ヘッダー HTTP 名はの誤字 referrer を使用している。 |
| レート(リクエスト/期間) | 10分あたり100リクエスト |
| アクション | ブロック |
この例示ルールには高度なレート制限が必要です。
クレデンシャルスタッフィング対策
レート制限を利用することで、ログインエンドポイントをクレデンシャルスタッフィング攻撃から保護することができます。 クレデンシャルスタッフィングは、攻撃者が自動化されたスクリプトを使用して、ログインフォームで複数のユーザー名とパスワードの組み合わせを試行する際に発生します。 レート制限は、同一IPアドレスからの繰り返し失敗したログイン試行を制限することで、これらの攻撃を軽減するのに役立ちます。
以下の例は、失敗したログイン試行回数に基づいて制限とペナルティを強化する3つのレート制限ルールを示しています。
ルール1:初期保護閾値
ルール1では、1分間に最大4回のログイン失敗が許可されます。 制限を超過した場合、システムはマネージドチャレンジをトリガーします。 この設定は、正当なユーザーが時折発生するログインエラーから回復するのを支援すると同時に、自動化されたボットを抑制します。
| 設定 | 値 |
|---|---|
| マッチング基準 | ホスト名が等しい example.com かつ URI パスが等しい /login かつ リクエストメソッドが等しい POST |
| 式 | http.host eq "example.com" and http.request.uri.path eq "/login" and http.request.method eq "POST" |
| 計数特性 | IP |
| カウンタをインクリメントするとき | URIパスが等しい /login かつ メソッドが等しい POST かつ 応答コードが (401, 403) の範囲内 |
| 計数式 | http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403} |
| レート(リクエスト/期間) | 4リクエスト / 1分 |
| アクション | 管理対象チャレンジ |
規則2:中間保護閾値
正規ユーザーがルール1のレート制限に達した際にチャレンジを通過した場合、ルール2は失敗したログイン試行を継続するクライアントに対して追加の保護を適用する。 10分間に最大10回の失敗を試行できるが、それ以降は別のマネージドチャレンジがトリガーされる。
| 設定 | 値 |
|---|---|
| マッチング基準 | ホスト名が等しい example.com かつ URI パスが等しい /login かつ リクエストメソッドが等しい POST |
| 式 | http.host eq "example.com" and http.request.uri.path eq "/login" and http.request.method eq "POST" |
| 計数特性 | IP |
| カウンタをインクリメントするとき | URIパスが等しい /login かつ リクエストメソッドが等しい POST かつ レスポンスステータスコードが (401, 403) の範囲内 |
| 計数式 | http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403} |
| レート(リクエスト/期間) | 10リクエスト / 10分 |
| アクション | 管理対象チャレンジ |
規則3:厳格な保護基準
ルール3は、1時間以内に20回のログイン失敗があった場合、該当IPアドレスを1日間ブロックすることで、ルール2の閾値を超えたクライアントに対してより厳しい罰則を適用します。 このルールは、執拗な攻撃試行に対する最終的な防御策を提供する。
| 設定 | 値 |
|---|---|
| マッチング基準 | ホストは等しい example.com |
| 式 | http.host eq "example.com" |
| 計数特性 | IP |
| カウンタをインクリメントするとき | URIパスが等しい /login かつ リクエストメソッドが等しい POST かつ レスポンスステータスコードが (401, 403) の範囲内 |
| 計数式 | http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403} |
| レート(リクエスト/期間) | 1時間あたり20リクエスト |
| アクション | 1日間ブロック |
これらのルール例はすべて、「ビジネスプラン」以上のプランが必要です。
これらの3つのルールは、ルール式(緩和式とも呼ばれる)とは別のカウント式を持つ。 個別のカウント式を設定すると、アクションがトリガーされた際にその一致条件が使用されます。 カウント式では、 HTTP レスポンスステータスコードや HTTP レスポンスヘッダーに基づく条件を含めることで、レート制限をバックエンドロジックと統合できます。
また、2つの異なる式(カウント式とルール/緩和式)を定義することもできます。具体的には:
- レートを計算するために使用されたリクエスト。
- 実際に処理されたリクエスト
例えば、ルール3の例では、ステータスコード 401``403HTTP 200または400を /login 返したリクエスト POST を考慮してレートを計算します。 ただし、レート制限を超過した場合、同一IPから生成されるホスト example.com への全リクエストをブロックする CIS。
操作数の制限
レート制限を使用して、クライアントが特定の時間内に実行する操作の数を制御できます。 設定するルールは、アプリケーションの動作とリスクプロファイルによって異なります。
以下の例は、コンテンツのスクレイピングや自動化された活動を防止する方法を示しています。これらはシステムに過負荷をかけたり、データを悪用したりする可能性があります。 例としては、クエリ文字列、JSONボディパラメータ、またはボットの特性によるリクエスト制限が挙げられる。
クエリ文字列を使用したコンテンツスクレイピングの防止
この例では、クライアントはクエリ文字列パラメータを通じて、eコマースウェブサイト上で操作(価格検索や商品カートの追加など)を実行します。 例えば、クライアントから送信される典型的なリクエストは、以下のようなものになる可能性があります:
GET https://store.com/merchant?action=lookup_price&product_id=215
Cookie: session_id=12345
セキュリティチームは、ボット(ボット管理を CIS すり抜けた可能性があるもの)による店舗カタログ全体のスクレイピングを防ぐため、クライアントが価格を検索できる回数に制限を設けることを検討すべきです。
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant かつ URIクエリ文字列に含まれる action=lookup_price |
| 式 | http.request.uri.path eq "/merchant" and http.request.uri.query contains "action=lookup_price" |
| 計数特性 | IP |
| レート(リクエスト/期間) | 10リクエスト / 2分 |
| アクション | 管理対象チャレンジ |
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant かつ URIクエリ文字列に含まれる action=lookup_price |
| 式 | http.request.uri.path eq "/merchant" and http.request.uri.query contains "action=lookup_price" |
| 計数特性 | IP |
| レート(リクエスト/期間) | 5分間に20リクエスト |
| アクション | ブロック |
これらの2つのレート制限ルールは、選択されたアクション(この例では価格検索)を実行するリクエストにマッチし、カウント特性として IP を使用します。 同様に、 /login の例 と同様に、この2つのルールは、常連(ただし正当な)訪問者に対して誤検知を減らすのに役立ちます。
クエリ文字列パラメータを使用することで、 product_id 特定の項目の検索を制限できます。 クエリパラメータをカウント特性として追加することで、クライアントに関係なく、すべてのリクエストにわたってレートが計算されます。
次の例では、各リクエストに対する検索回 product_id 数を10秒間に50回に制限します。
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant |
| 式 | http.request.uri.path eq "/merchant" |
| 計数特性 | クエリ (product_id) |
| レート(リクエスト/期間) | 20リクエスト / 10秒 |
| アクション | ブロック |
この例示ルールには高度なレート制限が必要です。
予約や手配を扱うアプリケーションを保護するためにも、レート制限ルールを同じパターンで適用することができます。
リクエスト本文を使用したコンテンツスクレイピングの防止
リクエスト本文を通じてJSON形式で操作とそのパラメータを処理するアプリケーションを考えてみましょう。 たとえば、「 lookup_price 」という操作は、次のような形になる場合があります
POST https://api.store.com/merchant
Cookie: session_id=12345
Body:
{
"action": "lookup_price",
"product_id": 215
}
このシナリオでは、個々のセッションからのアクション数を制限するために、以下のルールを作成できます:
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant および JSON文字列が action 等しい lookup_price |
| 式 | http.request.uri.path eq "/merchant" and lookup_json_string(http.request.body.raw, "action") eq "lookup_price" |
| 計数特性 | クッキー (session_id) |
| レート(リクエスト/期間) | 10リクエスト / 2分 |
| アクション | 管理対象チャレンジ |
この例示ルールには、高度なレート制限とペイロード検査が必要です。
また、リクエストを発行するクライアントに関係なく、各ルック product_id アップの回数を制限することも可能です。次のようなルールを適用することで実現できます:
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant および JSONフィールドが action 等しい lookup_price |
| 式 | http.request.uri.path eq "/merchant" and lookup_json_string(http.request.body.raw, "action") eq "lookup_price" |
| 計数特性 | JSONフィールド (product_id) |
| レート(リクエスト/期間) | 50リクエスト / 10秒 |
| アクション | ブロック |
この例示ルールには、高度なレート制限とペイロード検査が必要です。
リクエスト本文がJSON形式でない場合、 [http.request.body.raw](/docs/cis?topic=cis-fields-functions-expressions#custom-rule-available-fields) field と正規表現(および [matches](/docs/cis?topic=cis-fields-functions-expressions&interface=ui#custom-rule-comparison-operators) 演算子)を使用して同じ目的を達成できます。
ボットからのリクエストを制限する
レート制限を使用して、ボットからの自動化されたトラフィックを制御できます。 一般的な手法として、大量の 403 または 404 レスポンスステータスコードを返すリクエストを監視する方法があります。これらは自動化されたスクレイピング活動を示すことが多いです。
この状況では、次のようなルールを設定することができます:
| 設定 | 値 |
|---|---|
| マッチング基準 | ホスト名は等しい example.com |
| 式 | http.host eq "example.com" |
| 計数特性 | IP |
| カウンタをインクリメントするとき | レスポンスステータスコードは (401, 403) の範囲内です |
| 計数式 | http.response.code in {401 403} |
| レート(リクエスト/期間) | 5件のリクエスト / 3分 |
| アクション | 管理対象チャレンジ |
このサンプルルールを利用するには、Businessプラン以上が必要です。
自動化されたソースによるアクションの実行速度を制御するには、 ボット管理 と併用してレート制限ルールを検討してください。 ボット管理では、 ボットスコア をマッチング基準の一部として使用し、自動化されたトラフィックまたは自動化の可能性が高いトラフィックにのみルールを適用できます。
例えば、自動化された可能性が高いトラフィックには最大スコア(またはしきい値) 30 を、自動化された 10 トラフィックには最大スコア(またはしきい値)を設定できます。
レート制限と ボット管理 を組み合わせることで、保護を強化できます。 ボット管理では、 ボットスコア をマッチング基準の一部として使用し、自動化されたトラフィックまたは自動化の可能性が高いトラフィックにのみルールを適用できます。
以下に例を示します。
- ボットスコアが 未満の場合、自動化されたトラフィックの
30可能性が高いことを示します。 - ボットスコアが 未満の場合、自動化されたトラフィックが
10確認されたことを示します。
セッションごとのリクエスト制限
アプリケーションがセッションクッキーを使用している場合、そのクッキーをカウント特性として使用してください。 この手法は、異なるIPアドレスからのリクエストを同一セッション内にグループ化します。分散型ボット攻撃の検知に有用です。
ルール 1
| 設定 | 値 |
|---|---|
| マッチング基準 | ボットスコアが30未満かつURIクエリ文字列に以下が含まれる場合 action=delete |
| 式 | cis.bot_management.score lt 30 and http.request.uri.query contains "action=delete" |
| 計数特性 | クッキー (session_id) |
| レート(リクエスト/期間) | 1分あたり10リクエスト |
| アクション | 管理対象チャレンジ |
ルール 2
| 設定 | 値 |
|---|---|
| マッチング基準 | ボットスコアが10未満で、URIクエリ文字列に以下が含まれる場合 action=delete |
| 式 | cis.bot_management.score lt 10 and http.request.uri.query contains "action=delete" |
| 計数特性 | クッキー (session_id) |
| レート(リクエスト/期間) | 5分間に20リクエスト |
| アクション | ブロック |
これらのサンプルルールには、高度なレート制限とボット管理が必要です。
指紋 JA3 の使用
アプリケーションがセッションクッキーを使用しない場合、個々のクライアントを識別するためにフィンガ JA3 ープリントを使用できます。 フィンガ JA3 ープリント は、 Bot Management をご利用のお客様が利用できる一意の識別子であり、同じクライアントからのリクエストを識別することを CIS 可能にします。 すべてのクライアントには、自動化されているか否かにかかわらず、関連付けられたフィンガープリントが存在する。
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /merchant かつ ボットスコアが10未満 |
| 式 | http.request.uri.path eq "/merchant" and cf.bot_management.score lt 10 |
| 計数特性 | JA3 指紋 |
| レート(リクエスト/期間) | 1分あたり10リクエスト |
| アクション | 管理対象チャレンジ |
このサンプルルールには、高度なレート制限とボット管理が必要です。
REST APIの保護
REST APIは、APIリクエストが頻繁に高負荷な処理や大規模なデータ検索を必要とするため、バックエンドシステムに高負荷をかける可能性があります。 制御されていないAPIアクセスは、パフォーマンスの低下やダウンタイムを引き起こす可能性があります。 高度なレート制限を使用して、悪用を防止し、ボリューム攻撃を軽減し、重要なリソースを保護します。
リソースの保護
リクエスト GET であっても、ファイルや画像などの大容量データのダウンロードに使用される場合、アプリケーションに負荷をかけたり帯域幅を消費したりすることがあります。
例えば、次のエンドポイントを考えてみましょう:
GET https://api.store.com/files/<FILE_ID>
Header: x-api-key=9375
不正利用を防ぎつつ正当なダウンロードを許可するため、個々のファイルごとに別々のルールを作成することなく、ファイルリクエストを制限するルールを定義できます。
| 設定 | 値 |
|---|---|
| マッチング基準 | ホスト名は に等しく api.example.com 、リクエストメソッドは に等しい GET |
| 式 | http.host eq "api.example.com" and http.request.method eq "GET" |
| 計数特性 | パス |
| レート(リクエスト/期間) | API Discoveryによって示唆されるか、過去のトラフィックを分析して評価される。 |
| アクション | ブロック |
この例示ルールには高度なレート制限が必要です。
このルールは、10分あたり1ファイルにつき10リクエストまで https://api.store.com/files/* ダウンロードを制限します。 Pathをカウント特性として使用することで、新しい <FILE_ID>.ごとに新規ルールを作成する必要がなくなります。 料金はファイル単位で計算され、クライアントのIPアドレスやセッションIDには依存しません。
クライアント識別子(例: `x-api-key` や ` `IP)と Path 組み合わせることで、保護をさらに強化できます。 この方法により、特定のクライアントが特定のファイルに対して行えるダウンロード回数を制限できます。
| 設定 | 値 |
|---|---|
| マッチング基準 | ホスト名は に等しく api.store.com 、リクエストメソッドは に等しい GET |
| 式 | http.host eq "api.example.com" and http.request.method eq "GET" |
| 計数特性 | パスとヘッダー (x-api-key) |
| レート(リクエスト/期間) | API Discoveryによって示唆されるか、過去のトラフィックを分析して評価される。 |
| アクション | ブロック |
この例示ルールには高度なレート制限が必要です。
API GraphQL の保護
API GraphQL のサーバー過負荷防止は、RESTful APIの過負荷防止とは異なる場合があります。 このアーキテクチャで構築されたアプリケーションが抱える最大の課題の一つは、単一のパスが GraphQL サーバーへの全クエリを管理し、通常すべてのリクエストが単一 POST 操作である点である。 これにより、メソッドや HTTP URIパスに基づいて異なるAPIごとに異なるレート制限を設定することができなくなります。
ただし、RESTful APIのようにメソッドやパスを使用する代わりに、リクエストの目的は通常、ボディに埋め込まれています。ボディには、クライアントが取得または変更(サーバーサイドのデータ変更に関する GraphQL's 用語に従う)したいデータに関する情報と、アクションを実行するために必要な追加データが含まれています。
サーバーの過負荷を防ぐために、以下の対策を検討してください:
- 特定のユーザーが同一 GraphQL の操作名を呼び出せる回数を制限する。
- 特定のユーザーが要求できるクエリの複雑さの総量を制限する。
- 個々のリクエストのクエリの複雑さを制限する。
以下の例は、映画レビューを受け付けるアプリケーションに基づいています。
POST https://moviereviews.example.com/graphql
Cookie: session_id=12345
Body:
{
"data": {
"createReview": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}
操作数の制限
アクションの実行速度を制限するには、次のルールを作成します:
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスが等しい /graphql かつ ボディに含まれる createReview |
| 式 | http.request.uri.path eq "/graphql" and http.request.body.raw contains "createReview" |
| 計数特性 | クッキー (session_id) |
| レート(リクエスト/期間) | 5件のリクエスト / 1時間 |
| アクション | ブロック |
この例示ルールには、高度なレート制限とペイロード検査が必要です。
クエリの複雑さの総量を制限する
リクエスト GraphQL の処理の複雑さは大きく異なる場合があります。 APIが単一のエンドポイントを使用しているため、各リクエストが処理される前にその複雑性を判断することが困難である。
オリジンサーバーのリソース枯渇を防ぐため、リクエスト数を制限するのではなく、クライアントごとの時間経過に伴う総リクエストの複雑さを制限する。 CIS レート制限により、複雑性を経時的に追跡するルールを作成し、定義された複雑性予算を超過するリクエストをブロックできます。
この方法では、オリジンサーバーが各リクエストに複雑度スコアを割り当て、そのスコアを HTTP レスポンスヘッダーに含める必要があります。 その後、レート制限メカニズムはスコア情報を使用して、その特定のクライアントに対する複雑性予算を更新する。
以下の例は、1時間あたり1,000の総複雑性予算を定義します:
| 設定 | 値 |
|---|---|
| マッチング基準 | URIパスには以下が含まれます /graphql |
| 式 | http.request.uri.path eq "/graphql" |
| 計数特性 | クッキー (session_id) |
| 1ピリオドあたりの得点 | 1,000 |
| ピリオド | 1 時間 |
| レスポンスヘッダー名 | score |
| アクション | ブロック |
この例示ルールには、高度なレート制限とペイロード検査が必要です。
オリジンサーバーがリクエストを処理する際、レスポンスに scoreHTTP ヘッダーを追加します。その値は、リクエストを処理するためにオリジンサーバーが実行した作業量を示すものです。 例えば、100 です。 次の1時間において、同一クライアントは追加予算として最大までリクエスト 900 を実行できます。 この予算を超過すると、タイムアウトが切れるまで以降の要求はブロックされます。
個々のクエリの複雑さを制限する
API Shieldの顧客は、悪意のあるクエリ保護 GraphQL 機能を使用してAPI GraphQL を保護できます。 この機能は、オリジンサーバーに過負荷をかけサービス拒否状態を引き起こす可能性のあるクエリを、受信 GraphQL トラフィックからスキャンします。
受信 GraphQL クエリの深さとサイズを制限するルールを作成できます。 これらのルールは、パフォーマンスに影響を与える前に、不審なクエリや過度に複雑なクエリをブロックするのに役立ちます。