オープン・ワールドワイド・アプリケーションセキュリティプロジェクト

API4:2023 Unrestricted Resource Consumption

脅威要因 / 攻撃ベクトル セキュリティ弱点 影響
API固有:悪用可能性 平均 普及度 広範:検出可能性 簡単 技術的 深刻:特定のビジネスに依存
悪用には簡単なAPIリクエストが必要です。単一のローカルコンピュータまたはクラウドコンピューティングリソースを使用して、複数の同時リクエストが行われることがあります。トラフィックの高負荷によるDoS攻撃を引き起こすために設計された自動化ツールのほとんどがAPIのサービスレートに影響を与えます。 クライアントの相互作用またはリソース消費を制限しないAPIを見つけるのは一般的です。リクエストのパラメータによってリソースの数を制御するものや、応答のステータス/時間/長さの分析を行うことで問題を特定できます。バッチ処理も同様です。脅威要因はコストの影響を直接見ることができないが、サービスプロバイダ(例:クラウドプロバイダ)のビジネス/価格モデルに基づいてそれを推定できます。 悪用によりリソース枯渇によるDoS攻撃が発生する可能性がありますが、それによりCPU需要が高まり、クラウドストレージの必要性が増加するなど、インフラ関連の運用コストも増加する可能性があります。

APIは脆弱ですか?

APIリクエストを満たすためには、ネットワーク帯域幅、CPU、メモリ、ストレージなどのリソースが必要です。これらの必要なリソースは、API統合を通じてサービスプロバイダによって提供され、リクエストごとに支払われます(例:電子メール/SMS/電話の送信、生体認証の検証など)。

少なくとも次のいずれかの制限が欠落しているか不適切に設定されている場合、APIは脆弱です:

  • 実行タイムアウト
  • 最大割り当て可能メモリ
  • 最大ファイル記述子数
  • 最大プロセス数
  • 最大アップロードファイルサイズ
  • 単一のAPIクライアントリクエストで実行する操作の数(例:GraphQLのバッチ処理)
  • 単一のリクエスト-レスポンスで返すページごとのレコード数
  • サードパーティサービスプロバイダの支出限度額

攻撃シナリオの例

シナリオ #1

あるソーシャルネットワークはSMS検証を利用した「パスワードを忘れた」フローを実装し、ユーザーがパスワードをリセットするためにSMS経由でワンタイムトークンを受け取れるようにしています。

ユーザーが「パスワードを忘れた」をクリックすると、ユーザーのブラウザからバックエンドAPIへ次のAPIコールが送信されます:

POST /initiate_forgot_password

{
  "step": 1,
  "user_number": "6501113434"
}

その後、バックエンドからはSMS送信を担当する第三者APIへのAPIコールが裏で送信されます:

POST /sms/send_reset_pass_code

Host: willyo.net

{
  "phone_number": "6501113434"
}

第三者プロバイダであるWillyoはこの種の呼び出しに対して$0.05を請求します。

攻撃者はスクリプトを作成し、最初のAPIコールを何万回も送信します。バックエンドはWillyoに何万件ものテキストメッセージ送信を要求し、数分で数千ドルの損失を引き起こします。

シナリオ #2

GraphQL APIエンドポイントではユーザーがプロフィール画像をアップロードできます。

POST /graphql

{
  "query": "mutation {
    uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {
      url
    }
  }"
}

アップロードが完了すると、APIはアップロードされた画像を基に複数の異なるサイズのサムネイルを生成します。このグラフィカル操作はサーバーの多くのメモリを使用します。

APIは伝統的なレート制限保護を実装しています – ユーザーは短期間で多くの回数GraphQLエンドポイントにアクセスできません。また、アップロードされた画像のサイズもサムネイル生成前に確認します。

攻撃者はGraphQLの柔軟な性質を利用してこれらのメカニズムを簡単にバイパスできます:

POST /graphql

[
  {"query": "mutation {uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  {"query": "mutation {uploadPic(name: \"pic2\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  ...
  {"query": "mutation {uploadPic(name: \"pic999\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
}

APIは uploadPic 操作の試行回数を制限していないため、この呼び出しはサーバーメモリの枯渇とDoS攻撃を引き起こします。

シナリオ #3

サービスプロバイダは、クライアントがそのAPIを使用して任意の大きなファイルをダウンロードできるようにしています。これらのファイルはクラウドオブジェクトストレージに保存され、頻繁に変更されません。サービスプロバイダは帯域幅消費を低く保つためにキャッシュサービスに依存しています。キャッシュサービスは15GBまでのファイルのみをキャッシュします。

ファイルの1つが更新されると、そのサイズが18GBに増加します。すべてのサービスクライアントは新しいバージョンをすぐに取得し始めます。クラウドサービスの最大コスト許容量や消費コストアラートがなかったため、次の月の請求額は平均US$13からUS$8,000に増加します。

予防方法

  • メモリ、CPU、リスタート数、ファイルディスクリプタ、プロセス数などを制限することが容易なソリューションを使用します(例:コンテナ/サーバーレスコード、例:Lambdasなど)。
  • すべての受信パラメータやペイロードの最大データサイズを定義し、それに対する制限を強制します。たとえば、文字列の最大長、配列内の要素の最大数、および最大アップロードファイルサイズ。
  • 定義された時間枠内でAPIとの相互作用を制限する(レート制限)。
  • ビジネスニーズに基づいてレート制限を微調整します。一部のAPIエンドポイントではより厳格なポリシーが必要な場合があります。
  • 単一のAPIクライアント/ユーザーが単一の操作(例:OTPの検証、ワンタイムURLの訪問なしでのパスワード回復のリクエスト)を実行できる回数や頻度を制限します。
  • クエリ文字列とリクエストボディパラメータの適切なサーバーサイドバリデーションを追加します。特に、レスポンスで返すレコードの数を制御するパラメータについて。
  • すべてのサービスプロバイダ/ API統合に対して支出制限を設定します。支出制限を設定できない場合は、代わりに請求アラートを設定します。

参考文献

OWASP

外部参考