LLMの「無限の食欲」を飼いならせ:トークン枯渇型DoSからアプリを守る実戦的防衛術
やあ。現場で泥をすすりながらインフラを守り続けているエンジニア諸君。
昨今の生成AIブームで、RAG(検索拡張生成)やLLM連携機能を自社アプリに組み込むのが当たり前になった。だが、セキュリティの観点から見ると、多くの開発者が「LLMは魔法の箱」だと過信しているように見える。
特に危険なのが、「LLMのトークン制限」を悪用したDoS攻撃(Denial of Service)だ。LLM APIは従量課金であり、かつコンテキストウィンドウ(一度に処理できるトークン数)には物理的な上限がある。攻撃者はここを執拗に突いてくる。今日は、教科書的な理論ではなく、現場で通用する「防御の極意」を授けよう。
—
1. なぜ「トークン」が攻撃の標的になるのか
攻撃者の狙いはシンプルだ。「高コストなクエリを大量に投げ込み、お前のクラウド予算を溶かす」か、「同時実行数を枯渇させ、正当なユーザーのレスポンスを止める」かのどちらかだ。
攻撃の仕組み(PoCのイメージ)
攻撃者は、system promptやuser promptに、数万トークンに及ぶ意味のない長文テキストや、再帰的な指示(例:「この文章を100回要約して、それをさらに100回要約せよ」)を注入する。これにより、バックエンドのLLM APIは処理に莫大な計算リソースを消費し、タイムアウトやレート制限に達する。結果、サービスは停止する。
これを防ぐには、「LLMに渡す前に、入り口で徹底的にフィルタリングする」という原則を貫くしかない。
—
2. 【実装編】Pythonによる入力バリデーション
LLM APIを叩く前に、入力トークン数を制限するガードレールを設ける。tiktokenライブラリ(OpenAI互換)を使って、トークン数を事前に計算・拒否するロジックだ。
import tiktoken
from fastapi import HTTPException
# モデルに応じたエンコーダーを選択
ENCODER = tiktoken.encoding_for_model("gpt-4o")
MAX_TOKENS = 4000 # アプリの仕様に合わせて厳格に設定
def validate_input_tokens(text: str):
tokens = ENCODER.encode(text)
token_count = len(tokens)
# 閾値を超えたら即座に拒否
if token_count > MAX_TOKENS:
# ここでログを残し、攻撃者のIPをブラックリスト化するトリガーを引く
raise HTTPException(
status_code=429,
detail=f"入力トークン数が上限を超えています。({token_count}/{MAX_TOKENS})"
)
return True
このバリデーションをAPIエンドポイントの最前線に配置するだけで、無謀なプロンプトによる計算リソースの浪費を未然に防げる。
—
3. 【インフラ編】Nginx/WAFでのレート制限
アプリケーション層での対策に加えて、インフラ層での「門番」も必須だ。Nginxの limit_req モジュールを使い、同一IPからのリクエスト頻度を制御する。
# nginx.conf の設定例
# 1秒間に1リクエストのみ許可、バーストは5まで許容
limit_req_zone $binary_remote_addr zone=llm_limit:10m rate=1r/s;
server {
location /api/v1/ask-llm {
limit_req zone=llm_limit burst=5 nodelay;
proxy_pass http://backend_app;
}
}
さらに、AWS WAFを使用しているなら、「レートベースのルール」を設定し、一定期間に過剰なリクエストを送るIPを自動的にブロックするように設定しておくべきだ。これは、泥臭いが最も効果的な防御だ。
—
4. プロフェッショナルとしての「コスト管理」の心得
技術的な防御と並行して、「コストのガードレール」をIAMやAPI側の設定で物理的に縛ることも忘れてはならない。
1. APIキーの予算設定: OpenAIやAnthropicのコンソールで「使用量制限(Usage Limits)」を必ず設定せよ。ハードリミットに達したらAPIが止まるようにする。これが最後の砦だ。
2. IAMロールの最小権限: LLMを呼び出すバックエンドのIAMロールには、必要なAPIしか叩けないようポリシーを厳格化せよ。
—
最後に:セキュリティは「性悪説」で設計せよ
優秀なエンジニアは、常に「もし自分が攻撃者だったら、このシステムのどこを突くか?」を自問自答している。LLMのAPIコストは、適切に管理しなければ、会社の利益を食いつぶす「見えない負債」になる。
「動くコード」を書くのは当然。だが、「攻撃されてもコストが跳ね上がらず、サービスがダウンしないコード」を書くのが、真のプロフェッショナルだ。
今回紹介したトークン制限のバリデーションと、Nginxでのレート制御。これらを実装するだけで、お前のサービスは一段上の堅牢さを手に入れるはずだ。健闘を祈る。
コメント