LLM の課金型 DoS — 落とさない。あなたの請求だけが伸びる

AI の API は使った文字数ぶん課金される。攻撃者はアプリを普通に使うだけで請求額を増やせる。サーバーは正常、エラーはゼロ、気づくのは請求書か止まったとき。5分でできる上限設定と、アプリ側の4点。

動画で見る

結論から

普通のサーバー攻撃は、アクセスを大量に浴びせてサイトを落とします。AI 機能に対する攻撃は、落としません。動かし続けます。 AI の API は使った文字数(トークン)ぶんだけ課金されるので、攻撃者はあなたのアプリを普通に使うだけで、あなたの請求額を増やせます。長い文章を投げ、長い返事を出させ、それを繰り返す。サーバーは正常、ログも正常、エラーもゼロ。気づくのは請求書か、上限に達してサービスが止まったときです。

この記事で伝えたいのは、この一点だけです。AI 機能を公開するということは、他人が押せる「課金ボタン」を置くこと。上限を設定していないなら、限度額なしのカードを画面に貼っているのと同じ。 盗まれた鍵で他人の AI 枠を使う「LLMjacking」を最初に報告したセキュリティ企業 Sysdig は、高性能モデルを回された場合の被害を1日あたり10万ドル超と見積もっています。盗まれた access は闇市場で月30ドル程度で売られていました。払うのは鍵の持ち主です。

  • 何が起きるか(① 鍵が漏れた場合):公開リポジトリや設定ミスから API キーを拾われ、他人のサービスの裏側であなたの枠が使われる。あなたのアプリのアクセス数は増えない
  • 何が起きるか(② 鍵は漏れていない場合):ログイン不要の AI チャットが「無料の AI」として使われる。あるいは長文を投げ続けられて、正常な利用の形のまま請求だけが伸びる
  • なぜ:AI の呼び出しは1回あたりの単価が桁違いに高く(普通のページ表示の数千倍のこともある)、しかも入力の長さで青天井に増える。攻撃に大量のアクセスが要らない
  • 直す:プロバイダ側の利用上限と請求アラートを先に設定する。アプリ側は「ログイン必須・1人あたりの回数制限・入力の長さ制限・最大出力の固定」の4点

動画版(約3分半)は本文の上に埋め込んであります。

① 何が起きるのか:アクセス数は増えないのに、請求だけが伸びる

パターン①:鍵が漏れる(LLMjacking)

2024年5月、Sysdig の調査チームが報告した攻撃です。攻撃者は公開リポジトリ、公開設定のままのストレージ、フロントエンドのコードから API キーを収集し、有効かどうかを機械的に判定します。OpenAI、Anthropic、Azure OpenAI、AWS Bedrock、Google Vertex AI。有効だったキーは、そのまま自分たちのサービスに使うか、中継サーバー経由で他人に転売します。買う側は月30ドル程度で「制限のない AI」を手に入れ、請求は鍵の持ち主に行きます。高性能モデルを回された場合、被害は1日10万ドルを超えるとされています。

この攻撃の嫌なところは、あなたのアプリには何の異常も出ないことです。アクセスは増えず、サーバーの負荷も変わらず、エラーも出ません。あなたの鍵が、あなたの知らない場所で使われているだけです。

パターン②:鍵は漏れていない

もっとありふれているのはこちらです。AI で作ったアプリに、ログイン不要の AI チャットや「AI で文章を生成」ボタンを付けた。誰でも押せます。そこに、こういうことが起きます。

  • 無料 AI として使われる:あなたのチャット欄が「登録不要で使える AI」として共有され、翻訳や宿題や小説の続きに使われる。使われるほど、あなたが払う
  • 入力で焼かれる:入力欄に10万字を貼り付けて送信する。1回の送信で、通常利用の数百回ぶんの費用が発生する
  • 出力で焼かれる:「1万字のレポートを書いて」と頼む。出力側の単価は入力の数倍で、こちらの方が高くつく
  • 繰り返される:上の操作を、簡単なスクリプトで一晩中回す。1台でできます

サーバーから見ると、これは全部「正常なリクエスト」です。DDoS(→ DDoS の記事)のように帯域を埋めるわけではないので、CDN の防御にも引っかかりません。OWASP は2025年版の LLM アプリ向け Top 10 で、この項目を「Model Denial of Service(サービス妨害)」から 「Unbounded Consumption(際限のない消費)」に改名しました。狙いはサービスを止めることではなく、消費させ続けることだからです。

鍵の流出と無制限利用の2経路、監視画面には何も出ないこと、効く対策

② なぜ起きるのか:1回のクリックの単価が、桁違いに高い

普通の Web ページは、1回表示しても費用はほぼゼロです。だから「大量に叩かれること」を前提に守りを作れば足ります。AI 機能は違います。1回の呼び出しに、はっきりとした原価がある。しかもその額は固定ではなく、送った文字数と返した文字数で決まります。つまり、攻撃者はリクエスト数を増やさなくても、1回あたりを大きくするだけで目的を達成できます。

守りの発想も変わります。「1秒に何回まで」だけでは足りません。「1回にどれだけの量まで」「1人が1日にいくらまで」を決める必要があります。

そしてもう1つ。止まるのも困るということです。上限を設定していれば請求は止まりますが、その瞬間にあなたの正規のユーザーも AI 機能を使えなくなります。攻撃者は、あなたのサービスを止めることにも成功します。だから「上限だけ」では不十分で、「上限+1人あたりの制限」がセットになります。誰か1人が全体の枠を食い尽くせない形にしておく、ということです。

AI はどう作るか。 「AI で要約する機能を付けて」と頼むと、AI ツールは API を呼ぶコードを書きます。そこに入っていないものが4つあります。入力の長さ制限、出力の上限(`max_tokens`)、1人あたりの回数制限、そしてログイン必須の判定です。頼まなければ、まず入りません。動作確認は自分1人が普通の長さの文章でやるので、何も問題は起きません。さらに、フロントエンドから直接 API を呼ぶ構成にされていると、キーがブラウザから丸見えになります(→ APIキーがフロントに出ている記事)。パターン①の入口はここが最多です。

③ どう直すのか:先に上限、次に4点

順番が大事です。コードを直す前に、プロバイダの管理画面で上限とアラートを設定してください。5分で終わり、最悪の事態(青天井の請求)だけは今日から防げます。

  • OpenAI:Settings → Limits で毎月の上限額(Budget)と通知メールのしきい値
  • Anthropic:Console の Billing / Usage limits で上限
  • AWS Bedrock / Google Vertex:AWS Budgets、Cloud Billing の予算アラート(プロジェクト単位)

そのうえで、以下をそのまま AI ツールに貼ってください。

「このプロジェクトで LLM の API を呼び出している箇所を全て挙げてください。各箇所について、次の5点を確認し、無ければ実装してください。①API キーがフロントエンド(ブラウザ側のコード・環境変数の NEXT_PUBLIC_ など)に露出していないか。露出していればサーバー経由の呼び出しに変更する。②ログインしていないユーザーが呼び出せる状態になっていないか。公開機能として必要な場合を除き、認証を必須にする。③1リクエストあたりの入力文字数の上限(例:4,000文字)を、サーバー側で検証しているか。④max_tokens(最大出力)を明示的に指定しているか。⑤同一ユーザー/同一 IP あたりの呼び出し回数の制限(例:1分5回・1日100回)が、サーバー側にあるか。加えて、モデル名をクライアントから指定できる実装になっていれば、サーバー側で固定してください。」

最後の「モデル名をクライアントから指定できる」は見落とされがちです。安いモデルを想定していても、リクエストの中身を書き換えて最上位モデルを指定されると、単価が一桁変わります。

④ 直ったかを確かめる:ログアウトして、自分で叩く

  • ログアウト状態で AI 機能を使ってみる。使えたら、それは世界中の誰でも使えるということ。意図した公開機能でなければ ✗
  • ブラウザの F12 →「ネットワーク」タブで AI 機能を1回実行し、リクエストの中身を見る。API キーらしき文字列(`sk-` で始まる等)が見えたら ✗(即座に鍵を無効化して再発行)
  • 長文を投げる:適当な文章を1万字ぶんコピペして送信。そのまま処理されたら ✗(上限で弾かれるべき)
  • 連打する:同じ操作を30秒間に20回。全部通ったら ✗(途中で「しばらく待ってください」と出るのが ◯)
  • 管理画面で上限額とアラートを確認。空欄なら ✗。使用量のグラフを開いて、身に覚えのない時間帯の山が無いかも見る(あれば鍵の流出を疑う)
  • 分からなければ、AIに「未認証リクエスト・10万文字入力・1分間に100回の連続呼び出しが、それぞれサーバー側で拒否されることを確認するテストを書いて」

自分で直せないとき:エンジニアに送る一文

「LLM API の呼び出しに、利用量の制限がありません。①キーのフロント露出の有無を確認、②AI 機能を認証必須に、③入力文字数の上限と max_tokens をサーバー側で強制、④ユーザー単位・IP 単位のレートリミットを追加、⑤プロバイダ側の月次上限と請求アラートを設定、をお願いします。モデル名はサーバー側で固定してください。」

よくある質問

個人開発の小さなアプリでも狙われますか。

狙われます。攻撃者は「そのアプリが有名かどうか」ではなく「鍵が有効かどうか」「制限が無いかどうか」で選びます。キーの収集は自動化されていて、公開リポジトリに置かれた鍵は数分で見つかります。むしろ、監視の目が少ない小さなアプリの方が長く使われます。

上限額を設定すれば、それで十分ですか。

被害額の上限は決まりますが、上限に達した瞬間にあなたのユーザーも使えなくなります。攻撃者の目的が「あなたのサービスを止めること」なら、それで達成されてしまう。だから上限に加えて、1人あたりの回数制限を必ず入れてください。

キーが漏れたかどうか、どうすれば分かりますか。

プロバイダの使用量グラフを見るのが最も早いです。自分が使っていない時間帯(深夜など)に一定の消費が続いていたら、ほぼ確実です。心当たりがあるなら、鍵の再発行は数分で終わるので、迷う前にやってください(→ 鍵が漏れたときの30分の記事)。

無料枠だけで運用しているので大丈夫ですか。

請求は来ませんが、枠を食い尽くされてサービスが止まります。また、無料枠のあるサービスは攻撃者にとっても価値があるため、鍵の転売対象になります。制限は同じように必要です。VibeCode本番化の無料相談でも、AI 機能の上限設定と鍵の置き場所は最初に見ています。