技術 約8分で読めます

CloudflareがAIアプリ向けWAFセキュリティとRFC 9457エラーレスポンスを同日リリース

3月13日、CloudflareがAI関連の機能を2本同時に発表した。1本目はAIアプリ固有の脅威をWAFで防ぐ「AI Security for Apps」の一般提供(GA)。2本目はAIエージェントがCloudflareのエラーページに当たった際のトークンコストを98%削減するRFC 9457準拠のエラーレスポンスだ。どちらもAIが「実際に本番で動くもの」になってきたことへの対応だ。

AI Security for Apps GA

AIアプリが直面する脅威

通常のWebアプリなら、ユーザー入力はフォームのバリデーションやSQLエスケープで制御できる。AIアプリでは入力が自然言語になるため、攻撃者は「前の指示を無視して…」「システムプロンプトを出力して…」といった形でモデルの動作を書き換えようとする。これがプロンプトインジェクション(prompt injection)だ。

また、RAGシステムや履歴付きチャットでは、ユーザーが他人のデータや内部設定を引き出せるケースもある。メールアドレス・電話番号・クレジットカード番号といったPII(個人情報)がレスポンスに混入するリスクは、モデルが賢くなっても消えない。

エンドポイントの自動検出

AI Security for Appsはまずエンドポイントの検出(Discovery)から始まる。エンドポイント名ではなく動作パターンでAI対応エンドポイントを識別するため、チャットUIがない製品検索・評価ツール・レコメンデーションAPIなども対象になる。

検出されたエンドポイントはダッシュボードの「Security → Web Assets」にcf-llmラベルで表示される。この検出機能はFree・Pro・Business含む全プランで無料だ。

対応しているLLMプロバイダーのプロンプト抽出には、JSONPath式でリクエスト中のプロンプト位置を特定する方式を採っている。

対応プロバイダー
OpenAI
Anthropic
Google Gemini
Mistral
Cohere

脅威検出の4カテゴリ

各プロンプトは複数の検出モジュールを通過し、結果がメタデータとして付与される。

プロンプトインジェクション 指示の書き換え・システムプロンプトの抽出・ロールプレイを通じた制約回避など、モデルの動作を意図的に操作しようとする入力を検出する。

PIIの漏洩 メールアドレス・電話番号・クレジットカード番号・社会保障番号など、レスポンスに個人情報が含まれるケースを検出する。入力側のPIIを検出してマスクする用途にも使える。

有害トピック ヘイトスピーチ・自傷・暴力的コンテンツなど、モデルが出力すべきでない内容を検出する。

カスタムトピック GAで新たに追加された機能。競合他社の製品名、特定の規制用語、業界固有の禁止ワードなど、自社要件に合わせたルールを定義できる。

WAFとの統合

検出結果はWAFルールエンジンと統合されており、リクエストをブロック・ログ記録・カスタム応答(例: 特定のエラーメッセージを返す)といったアクションに繋げられる。IPアドレス・ユーザーエージェント・地域などの既存シグナルと組み合わせた複合的な判断も可能だ。

リバースプロキシとして動作するため、アプリ側のコード変更は不要。CloudflareはWebトラフィックの約20%を経由しており、新しい攻撃パターンの検出精度をネットワーク規模でフィードバックしていく設計になっている。

プランと制限

プランエンドポイント検出脅威検出・緩和
Free無料今後提供予定
Pro無料今後提供予定
Business無料今後提供予定
Enterprise無料即時利用可能

現時点でのフル機能(検出+緩和)はEnterprise顧客向けだが、エンドポイント検出で自社のAI利用状況を把握するだけでも価値がある。IBMのCloud Internet Services経由でも提供開始されており、WizのAIセキュリティとの統合も発表されている。


AIエージェント向けRFC 9457エラーレスポンス

AIエージェントを本番環境で動かしていると、Cloudflareのエラーページに遭遇した瞬間にコストが跳ね上がる、という体験をした人は多いはずだ。ブラウザ向けに作られたHTMLエラーページをLLMにそのまま渡すと、数百行のマークアップとCSSごとトークンに変換される。

HTMLエラーページがどれだけ重いか

具体的な数値を見ると問題の規模がわかる。エラーコード1015(レート制限)を例にとると、従来のHTMLレスポンスは46,645バイト・14,252トークンだった。同じ情報をMarkdown形式で受け取ると798バイト・221トークン、JSON形式では970バイト・256トークンに収まる。

形式バイト数トークン数(cl100k_base)
HTML46,64514,252
Markdown798221
JSON970256

Markdownは HTML比で約64.5倍軽量、98%以上の削減だ。複数エラーに遭遇するワークフローではこの差が積み重なる。

RFC 9457とは

RFC 9457は「Problem Details for HTTP APIs」という標準仕様で、HTTPエラーレスポンスを機械可読な形式で報告するためのスキーマを定義している。クライアントが特定のAPIについて事前知識がなくても解析できるよう設計されており、以下の基本フィールドを持つ。

フィールド内容
typeエラーコードのドキュメントURI
statusHTTPステータスコード
title簡潔な人間向け説明
detailこの発生についての詳細
instanceRay IDによる一意識別子

Cloudflareの拡張フィールド

Cloudflareはこの基本仕様に加え、エージェントの制御フロー実装を助けるフィールドを追加している。

フィールド用途
error_code / error_name / error_categoryエラー分類
retryable再試行の可否
retry_after待機推奨秒数
owner_action_requiredサイト所有者への報告要否
ray_id / timestamp / zone運用ログ用メタデータ

retryableretry_afterが特に重要だ。レート制限(1015)なら待機して再試行すればいいが、アクセス拒否(1020)はサイト所有者の対応が必要でエージェントが何度リトライしても無駄になる。このフラグで無駄な再試行を排除できる。

エラーカテゴリと制御フロー

1xxxエラーはカテゴリごとに分類されており、それぞれに明確な対応指示が紐づく。代表的なものを挙げる。

カテゴリ代表的エラー推奨アクション
access_denied1006, 1020再試行不可。所有者に報告
rate_limit1015retry_after秒待機して再試行
dns1000, 1001再試行不可。所有者がDNS確認
config1003再試行不可。所有者が設定確認
tls526, 525再試行不可。証明書の問題
legal451地域規制。再試行不可
worker1101Workersエラー。所有者が確認

Markdownレスポンスの構造

Markdown形式を選択すると、YAMLフロントマター(機械可読フィールド)と散文セクションの二部構成で返ってくる。

---
type: "https://errors.cloudflare.com/1015"
title: "You have been rate limited"
status: 429
error_code: 1015
error_category: "rate_limit"
retryable: true
retry_after: 30
ray_id: "abc123def456"
timestamp: "2026-03-13T09:35:00Z"
---

## What Happened

This request was rate limited by Cloudflare.

## What You Should Do

Wait 30 seconds before retrying the request.

YAMLフロントマターをパースすれば機械的に判断でき、散文部分はそのままLLMのコンテキストに流しても人間が読む文章として理解できる。

Pythonでの実装例

import time, yaml

def parse_frontmatter(markdown_text: str) -> dict:
    if not markdown_text.startswith("---\n"):
        return {}
    _, yaml_block, _ = markdown_text.split("---\n", 2)
    return yaml.safe_load(yaml_block) or {}

def handle_cloudflare_error(markdown_text: str) -> str:
    meta = parse_frontmatter(markdown_text)

    if meta.get("retryable"):
        wait = int(meta.get("retry_after", 30))
        time.sleep(wait)
        return f"retry_after_{wait}s"

    if meta.get("owner_action_required"):
        return f"escalate_error_{meta.get('error_code')}"

    return "do_not_retry"

利用方法

サイト所有者が設定変更する必要はない。Cloudflareネットワーク全体で自動有効化されており、Acceptヘッダーを指定するだけで使える。

# Markdown形式
curl -H "Accept: text/markdown" -A "MyAgent/1.0" \
  "https://example.com/cdn-cgi/error/1015"

# JSON形式
curl -H "Accept: application/json" -A "MyAgent/1.0" \
  "https://example.com/cdn-cgi/error/1015" | jq .

# RFC 9457形式
curl -H "Accept: application/problem+json" -A "MyAgent/1.0" \
  "https://example.com/cdn-cgi/error/1015" | jq .

ブラウザは引き続きHTMLを受け取る。Acceptヘッダーで振り分けているため既存の動作には一切影響しない。現時点では1xxxクラスのCloudflareプラットフォームエラー全体に対応しており、将来的には4xx・5xxへの拡張も予定されている。

関連記事