以下に翻訳と指定の表形式化を反映しました。(References セクションは原文のままです)
API4:2023 リソース消費の無制限(Unrestricted Resource Consumption)
| Threat agents / Attack vectors(脅威エージェント/攻撃ベクター) | Security Weakness(セキュリティの弱点) | Impacts(影響) |
|---|---|---|
| API 固有:悪用難易度(Exploitability) 平均 悪用には単純な API リクエストで十分です。1 台のローカル PC からでも、クラウド計算資源を使ってでも、複数の同時リクエストを実行できます。一般に入手可能な自動化ツールの多くは、高トラフィックで DoS を引き起こし、API の処理能力(スループット)に影響を与えるよう設計されています。 |
蔓延度(Prevalence) 広範 : 検出可能性(Detectability) 容易 クライアントの相互作用やリソース消費を制限しない API はよく見られます。返却件数を制御するパラメータなどを含む 細工したリクエスト と、レスポンスのステータス/時間/サイズの分析により、問題を特定できます。バッチ操作でも同様です。脅威エージェントはコスト影響を直接は可視化できませんが、クラウド等の 料金モデル から推測可能です。 |
技術的影響(Technical) 重大 : ビジネス影響(Business) ケース依存 リソース枯渇による DoS を招くほか、CPU 需要の増加やクラウドストレージの増大など 運用コストの増加 にもつながります。 |
API は脆弱か?
API リクエストを処理するには、ネットワーク帯域・CPU・メモリ・ストレージなどのリソースが必要です。必要なリソースが API 連携で提供され、リクエストごとに課金(例:メール/SMS/電話の送信、生体認証の検証等)される場合もあります。
次の制限の いずれかが欠落、または 不適切(低すぎる/高すぎる) な場合、API は脆弱です:
- 実行タイムアウト
- 割り当て可能メモリの最大値
- ファイルディスクリプタの最大数
- プロセスの最大数
- アップロードファイルサイズの最大値
- 単一の API リクエストで実行できる 操作回数(例:GraphQL のバッチング)
- 単一のリクエスト-レスポンスで返せる 1 ページ当たりの件数
- サードパーティサービスに対する 支出上限
攻撃シナリオ例
シナリオ #1
あるソーシャルネットワークは SMS 検証を用いた「パスワードを忘れた」フローを実装しており、ユーザーはパスワードリセット用のワンタイムトークンを SMS で受け取れる。
ユーザーが「パスワードを忘れた」をクリックすると、ブラウザからバックエンド API へ次の呼び出しが送られる:
POST /initiate_forgot_password
{
"step": 1,
"user_number": "6501113434"
}
その後、バックエンドから SMS 配信を行う サードパーティ API へ内部呼び出しが送られる:
POST /sms/send_reset_pass_code
Host: willyo.net
{
"phone_number": "6501113434"
}
このプロバイダ Willyo は、この種類の呼び出し 1 件あたり $0.05 を課金する。
攻撃者が最初の API 呼び出しを 数万回 送るスクリプトを書くと、バックエンドは Willyo に連鎖して同数の SMS 送信を要求し、数分で数千ドルの損失が発生する。
シナリオ #2
ある GraphQL API はプロフィール画像のアップロードを許可している。
POST /graphql
{
"query": "mutation {
uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {
url
}
}"
}
アップロード完了後、API は画像から複数サイズのサムネイルを生成する。この処理はサーバメモリを多く消費する。
API は従来型のレート制限(短時間に過度なアクセスを禁止)と、サムネイル生成前の サイズ検査 を実装している。
しかし攻撃者は 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 に跳ね上がった。
防止方法(How To Prevent)
- コンテナやサーバレス(例:Lambdas)のように、メモリ・CPU・再起動回数・ファイルディスクリプタ/プロセス数 を容易に制限できるソリューションを使用する。
- すべての入力パラメータ・ペイロードに 最大サイズ を定義・強制する(文字列長、配列要素数、アップロードファイルサイズ(ローカル/クラウド保管を問わず)など)。
- 一定時間内にクライアントが API とやりとりできる頻度を制限する(レート制限)。
- レート制限は 業務要件に合わせて調整 する。エンドポイントによってはより厳格なポリシーが必要。
- 単一クライアント/ユーザーが 特定の操作 を実行できる回数・頻度を制限/スロットルする(例:OTP 検証、ワンタイム URL を踏まずにパスワード回復を要求する等)。
- クエリ文字列やリクエストボディの 返却件数を制御するパラメータ について、適切なサーバサイド検証を追加する。
- すべてのサービスプロバイダ/API 連携に 支出上限 を設定する。上限設定が不可能な場合は 課金アラート を構成する。
References
OWASP
- "Availability" - Web Service Security Cheat Sheet
- "DoS Prevention" - GraphQL Cheat Sheet
- "Mitigating Batching Attacks" - GraphQL Cheat Sheet