アクティブ防御:ステートフルなAPI脆弱性スキャナーの導入
セキュリティは伝統的に防御のゲームです。壁を築き、門を設け、疑わしいトラフィックを遮断するルールを書きます。長年にわたり、Cloudflareはこの分野のリーダーでした:私たちの Application Security プラットフォームは、攻撃を進行中に検知し、悪意あるリクエストをオリジンに到達する前にエッジで破棄するよう設計されています。
しかし、APIセキュリティにおいては、ただ防御的に構えるだけでは不十分です。そこで本日、Cloudflareの Web and API Vulnerability Scanner のベータ版を発表します。本リリースでは OWASP API Top 10 の中でも最も広範かつ検出が難しい脅威である Broken Object Level Authorization(BOLA)から着手します。今後、APIおよびウェブアプリケーションの脆弱性スキャンの種類を順次追加していきます。
今日最も危険なAPIの脆弱性は、一般的なインジェクション攻撃やWAFが容易に検出できるような不正なリクエストではありません。プロトコルやアプリケーション仕様には合致するが、ビジネスロジックに反する「ロジックの欠陥」です。これを見つけるには、攻撃が来るのを待つのではなく、能動的に探索する必要があります。
Web and API Vulnerability Scanner はまず API Shield のお客様向けに提供されます。なぜ今回の初期リリースで API セキュリティスキャンに注力しているのか、以下で説明します。
なぜ純粋に防御するだけでは不十分なのか
ウェブアプリケーションの世界では、脆弱性はしばしば構文エラーのように見えます。SQLインジェクションはデータが来るべき場所にコードが紛れ込んでいるように見えます。クロスサイトスクリプティング(XSS)はフォームフィールドにスクリプトタグが含まれているように見え、これらはシグネチャを持ちます。
APIの脆弱性はそれとは異なります。例を挙げましょう。フードデリバリーのモバイルアプリがバックエンドのAPIとだけ通信するとします。orders エンドポイントを見てみます。
- エンドポイント定義:
/api/v1/orders
- メソッド/リソース/パス/説明:
GET /api/v1/orders/{order_id} — ステータス確認。特定の注文の追跡状況を返す(例:「キッチンで調理中」)。
PATCH /api/v1/orders/{order_id} — 注文更新。配送先の変更や配達指示を付加することを許可。
BOLA のような権限破壊攻撃では、ユーザーA(攻撃者)がユーザーB(被害者)の有料注文の配送先を更新しようとします。攻撃者は単に被害者の {order_id} を PATCH リクエストに挿入します。以下は、被害者の注文ID を 8821 としたときのリクエスト例です。ユーザーA は自身の有効なトークンで正しく認証されています。
PATCH /api/v1/orders/8821 HTTP/1.1
Host: api.example.com
Authorization: Bearer <User_A_Valid_Token>
Content-Type: application/json
{
"delivery_address": "123 Attacker Way, Apt 4",
"instructions": "Leave at front door, ring bell"
}
リクエストヘッダーは有効で、認証トークンも有効、スキーマも正しい。標準的なWAFから見ると、このリクエストは完璧に見えます。ボット管理のソリューションでも、人間が手動で攻撃リクエストを送ると騙されるかもしれません。結果として、ユーザーA が B の注文を渡し先に変更してしまいます。
この脆弱性は、APIがユーザーAが本当にユーザーBのデータを表示または更新する権限を持っているかを検証していない、というロジックの欠落が原因です。構文の失敗ではありません。修正するには、API開発者は単純なチェックを実装できます:
if (order.userID != user.ID) throw Unauthorized;
この種の脆弱性は、能動的にAPIテストトラフィックを送信するか、既存のAPIトラフィックを受動的に傍受することで検出できます。受動的スキャンでこれらを見つけるには、文脈が必要です。昨年、私たちは API Shield 向けに BOLA 脆弱性検出をローンチしました。この検出は、顧客トラフィックを受動的にスキャンして利用パターンの異常を自動的に見つけます。
この種のスキャンで成功するには、何が「有効な」APIコールか、変数パラメータが何か、典型的なユーザーの動作がどうか、それらのパラメータを操作したときにAPIがどう振る舞うかを知る必要があります。しかし、セキュリティチームがそのようなコンテキストを持たない理由もあります。開発環境ではテストが必要でもユーザートラフィックがないかもしれません。本番環境は(幸いにも)攻撃トラフィックが不足しているが解析は必要、などです。
こうした状況や一般的に能動的に振る舞うために、チームは Dynamic Application Security Testing(DAST)に頼ることができます。DAST ツールは、セキュリティテストを目的とした新しいトラフィックプロファイルを作成することで、任意の環境でいつでも脆弱性を探査できます。
しかし従来の DAST ツールには導入のハードルが高い問題があります。設定が難しく、Swagger/OpenAPI ファイルを手動でアップロード・維持する必要があり、複雑なモダンなログインフローに正しく認証するのが苦手で、API固有のセキュリティテスト(例:BOLA)を欠く場合があります。
Cloudflare の API スキャンの利点
上のフードデリバリー例では、攻撃者が有効な注文を見つけられることを前提にしました。実稼働環境では攻撃者がこの種の情報を集める道がある一方で、セキュリティテストではまず自分でオブジェクトを作成してからAPIの認可制御を検証する必要があります。多くのスキャナーは各リクエストを個別に扱い、このような一連のリクエストを論理的に連鎖させて扱うことができません。これでは権限破壊のような脆弱性を発見できません。
また従来の DAST スキャナーはセキュリティツール群やオーケストレーションの中で孤立し、検出結果を共有・コンテキスト表示できないことがあります。
Cloudflare の脆弱性スキャンが異なる主な理由は次のとおりです。
- Security Insights に新しいスキャン結果を既存の Cloudflare セキュリティ検出と並べて表示し、文脈を付与します。ポスチャ管理情報を一箇所で確認できます。
- 既に API の入出力を把握していること。API Shield のお客様であれば、Cloudflare は既にあなたのAPIを理解しています。API Discovery と Schema Learning 機能が受動的にエンドポイントをカタログ化し、トラフィックパターンを学習します。初期リリースでは OpenAPI スペックを手動でアップロードする必要がありますが、将来のリリースではそれなしでも迅速に開始できるようになります。
- エッジに位置するため、受動的なトラフィック検査の知見を能動的インテリジェンスに変換できます。トラフィック検査で見つかった BOLA リスクを、脆弱性スキャナーで新しいHTTPリクエストを送信して簡単に検証できます。
- 新しいステートフルな DAST プラットフォームを構築しました。多くのスキャナーは "ツールにAPIの話し方を教える" のに数時間を要しますが、Cloudflare ではそのステップを事実上省略できます。あなたがAPIの認証情報を提供すれば、私たちがAPIスキーマを使って自動的にスキャンプランを構築します。
自動スキャンプランの構築
APIは一般的に OpenAPI スキーマでドキュメント化されています。これらのスキーマはホスト、メソッド、パス(いわゆる「エンドポイント」)および期待されるリクエストパラメータやレスポンスを定義します。自動的にスキャンプランを作るには、まず対象となるAPI仕様を解釈する必要があります。
当社のスキャナーは、OpenAPI ドキュメントから API コールグラフを構築し、それを辿ることで動作します。ここで重要なのは「攻撃者」と「所有者」というコンテキストを使う点です。所有者はリソースを作成し、攻撃者はその後にそれらへアクセスを試みます。攻撃者は自身の有効な認証情報で完全に認証された状態です。攻撃者が所有していないリソースを読み取り・変更・削除できれば、認可の脆弱性が検出されます。
たとえば上の配送注文 8821 を考えると、サーバー側のリソースが存在するためには、最初に所有者がそのリソースを作成している必要があります。多くの場合、これは依存関係の少ない「ジェネシス」POSTリクエストで作成されます。APIをコールグラフとしてモデル化すると、そのようなエンドポイントは入力エッジ(依存関係)がほとんどないノードになります。攻撃者のPATCHのような後続リクエストは、ジェネシスのリクエストが生成したデータ(この場合は order_id)にデータ依存します。データが揃っていなければPATCHは進めません。
以下の例では、POST /api/v1/orders/{order_id}/note/{note_id} へ注釈を追加するために訪問する必要がある API グラフのノードが(図示では紫の矢印で)示されます。重要なのは、図に示されるいかなるステップやロジックも OpenAPI 仕様には記載されていないという点です!これらは別の手段で論理的に推論されなければならず、当社の脆弱性スキャナーはこれを自動的に行います。
多様なAPIに対して確実かつ自動的にスキャンを計画するには、これらのエンドポイント関係をゼロから正確にモデル化する必要があります。しかし、2つの問題が生じます:API仕様のデータ品質は保証されないこと、そして機能的に完全なスキーマでも命名が曖昧な場合があることです。
簡略化した OpenAPI 仕様は例えば次のように見えるかもしれません。
openapi: 3.0.0
info:
title: Order API
version: 1.0.0
paths:
/api/v1/orders:
post:
summary: Create an order
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
product:
type: string
count:
type: integer
required:
- product
- count
responses:
'201':
description: Item created successfully
content:
application/json:
schema:
type: object
properties:
result:
type: object
properties:
id:
type: integer
created_at:
type: integer
errors:
type: array
items:
type: string
/api/v1/orders/{order_id}:
patch:
summary: Modify an order by ID
parameters:
- name: order_id
in: path
POST エンドポイントが次のようなレスポンスを返すことが分かります。
{
"result": { "id": 8821, "created_at": 1741476777 },
"errors": []
}
人間の観察者にとっては、$.result.id が PATCH エンドポイントの order_id に注入すべき値であることはすぐに明らかです。しかし id が orderId や value と呼ばれていたり、任意のネスト構造にある場合もあり得ます。こうした OpenAPI ドキュメント内の微妙な不整合は、単純なヒューリスティックでは取り扱いが困難です。
当社のスキャナーは、この曖昧な問題領域に対処するために Cloudflare の Workers AI プラットフォームを利用します。OpenAI の open-weight モデル gpt-oss-120b のようなモデルは、データ依存関係を高精度でマッチングし、必要に応じて現実的な偽データを生成して OpenAPI 仕様の空白を埋めるのに十分強力です。構造化出力を活用することで、モデルは当社のスキャナーが辿るための API コールグラフ表現を生成し、攻撃者と所有者の認証情報を適切に注入します。
このアプローチは、OpenAPI スキーマ内の認可やデータ関係を推論するために人間の知性を必要とする問題を、人工知能で代替するものです。構造化出力は、gpt-oss の自然言語の世界と機械実行可能な指示の橋渡しを行います。
Workers AI によるプランニング問題の解決に加え、Workers AI を自社ホスティングすることで、当社のシステムは Cloudflare の高可用でグローバルに分散されたアーキテクチャの恩恵を自動的に受けます。
実績ある基盤の上に構築
顧客の API 認証情報を扱うに足る信頼を得る脆弱性スキャナーを構築するには、実績あるインフラが必要です。ここで私たちは車輪の再発明はしていません。代わりに、スキャナープラットフォームの2つの重要コンポーネント、スキャナーのコントロールプレーンとシークレットストアに関して、Cloudflare 内で既に検証・展開されているサービスと統合しました。
- スキャナーのコントロールプレーンは Scan Orchestration のために Temporal と統合しています。Cloudflare の他の内部サービスが既に依存しているもので、各スキャンで実行される多数のテストプランの複雑性を Temporal の durable execution フレームワークが効果的に管理します。
- バックエンドは全て Rust で記述されています。Rust は Cloudflareのインフラサービスで広く採用されており、これにより内部ライブラリを再利用できるようになっています。
This lets us reuse internal libraries