【入門編】 LLMのトークン消費量監視によるDoS攻撃検知 – ガバナンス・リスク管理 & 生成AIセキュリティ防御ガイド

こんにちは!生成AIの波に乗って、日々のアプリ開発やサービス運営に奔走されていることと思います。最近は、自分たちのシステムにChatGPTなどのLLM(大規模言語モデル)を組み込むのが当たり前になってきましたよね。

でも、ちょっと待ってください。AIの導入で便利になった裏側で、「今までにない新しいサイバー攻撃のカタチ」が水面下で猛威を振るっているのをご存知でしょうか?

今回は、新人のIT担当者や「セキュリティはちょっと苦手…」という開発者のあなたに向けて、AIサービスの命綱である「LLMのトークン消費量を監視したDoS(サービス妨害)攻撃の検知と対策」について、身近な例えを交えながら一歩ずつ優しく紐解いていきたいと思います。

—

1. 家の鍵をこじ開けられる?AI特有の「新しいDoS攻撃」とは

まずは、従来のWebサービスに対する攻撃と、AI(LLM)に対する攻撃の違いを知ることから始めましょう。

従来のDoS攻撃と「トークン消費攻撃」の決定的な違い

これまでのWebサイトに対するDoS攻撃(例えば、大量のアクセスを一斉に送りつけてサーバーをダウンさせる嫌がらせ)は、いわば「ガヤガヤと大勢の人がお店のドアを同時に激しく叩き続ける」ようなものでした。サーバーの「通信量」や「同時接続数」をパンクさせるのが目的です。

一方、LLMを狙った攻撃はもっと巧妙です。これを身近な例でたとえてみましょう。

> 【防犯のたとえ:ファミレスのオーダー無限ループ事件】
>
> あなたがファミリーレストランの店長だと想像してください。お店には「お客様が注文した料理を、シェフが心を込めて作る」というルールがあります。
>
> そこへ、悪意を持った客がやってきて、こう注文しました。
> 「『あ』という文字を100万回繰り返した作文を作って。あと、その理由を宇宙の歴史の始まりから現代まで漏れなく、1文字も端折らずに説明して」
>
> シェフ(LLM)は真面目なので、その途方もない注文を何時間もかけて必死に作り続けなければなりません。その間、シェフは他の普通のお客さんの注文を一切受けられなくなってしまいますよね。結果、お店の厨房(サーバー資源)は大パニックになり、サービスは停止してしまいます。

これが、LLMにおける「トークン消費型DoS攻撃(資源枯渇攻撃)」のメカニズムです。

「トークン」ってなに?

LLMの世界では、言葉をそのまま理解するのではなく、文章を細切れのパーツ(=トークン)に分解して処理しています。大まかに言うと、日本語なら「1文字〜数文字=1トークン」くらいのイメージです。

AIのAPI(OpenAIやAnthropicなど)は、私たちが送る「プロンプト(入力)」の長さと、AIが返してくれる「レスポンス(出力)」の長さ、その両方のトークン数に応じて料金が発生し、かつサーバーの計算パワーを消費します。

攻撃者はこの仕組みを悪用し、AIが長文を生成せざるを得ない「巧妙に罠を仕掛けた長文プロンプト」を送りつけて、あなたのお財布(API利用料)をすっからかんにさせたり、サーバーをダウンさせたりするのです。恐ろしいですよね。だからこそ、これを監視してブロックする仕組みが絶対に必要なんです。

—

2. 現場で使える!トークン消費量を監視・制限する仕組み

では、どうやってこの攻撃から私たちのAIサービスを守ればよいのでしょうか?
答えはシンプルです。「お店に入る前にお客さんの荷物の大きさを測り、大きすぎる荷物は持ち込み禁止にする(レート制限)」そして「厨房で今どれくらい手間がかかっているかを常に監視する(アラート検知)」ことです。

ここでは、Node.js(Express)を使った簡単なWebサーバーを例に、リクエストに含まれるトークン量をチェックして制限をかける実用的なコードを見ていきましょう。

実装サンプル:簡易トークンカウンターとレート制限

実際の現場では、AIにリクエストを投げる前に「入力された文章の長さ(トークン数)」を概算し、あらかじめ決めた上限を超えていたらその場で「お断り(エラー)」を返す防衛策を講じます。

const express = require('express');
const app = express();

app.use(express.json());

// 【セキュリティ設定】1つのリクエストで許可する最大入力トークン数の上限
// 日本語の場合、1文字あたり約1〜2トークンとして概算値(安全のため厳めに設定)
const MAX_INPUT_TOKENS_LIMIT = 2000;

/**
 * 簡易的なトークン数見積もり関数
 * (本番環境では、各AIプロバイダーが提供する正確なTokenizerライブラリを使用してください)
 */
function estimateTokenCount(text) {
    if (!text || typeof text !== 'string') return 0;
    // 簡易的に文字数をベースにトークン数を推測(日本語を考慮して少し余裕を持たせる)
    return Math.ceil(text.length * 1.5);
}

// AI連携のエンドポイント
app.post('/api/chat', (req, res) => {
    const userPrompt = req.body.prompt;

    // 1. 入力されたプロンプトのトークン数を計算(見積もり)
    const tokenCount = estimateTokenCount(userPrompt);

    // 2. 制限値を超えているかチェック
    if (tokenCount > MAX_INPUT_TOKENS_LIMIT) {
        // ログに攻撃の兆候として記録する(SIEMや監視ツールへ連携)
        console.warn(`[セキュリティ警告] 制限値を超える大量トークンを検知しました。推測トークン数: ${tokenCount}`);

        // クライアントへエラーを返す
        return res.status(429).json({
            error: "Too Many Requests",
            message: "入力された文章が長すぎます。もう少し短くまとめてから送信してください。"
        });
    }

    // 3. 正常な範囲内であれば、この後AIモデル(API)へ処理を委譲する
    // aiService.generate(userPrompt);

    return res.status(200).json({
        success: true,
        estimatedTokens: tokenCount,
        message: "リクエストを受け付けました。"
    });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`AIプロテクトサーバーがポート ${PORT} で起動しました。`);
});

コードのポイント

  • estimateTokenCount 関数: 本番ではAIのベンダー(OpenAIのtiktokenなど)が用意している正確なトークン計算ライブラリを使うのがベストですが、上記のようにお手製の簡易ロジックでも「異常な長文」を弾く一次防御壁として十分に機能します。
  • HTTPステータスコード 429 (Too Many Requests): 「あなたは短時間にたくさんのリクエストを送りすぎました」という世界共通の合図です。このレスポンスを返すことで、悪意あるスクリプトの暴走をストップさせることができます。

—

3. インフラと監視の現場:アラート設定の極意

コードで水際対策をするのと並行して、インフラ側(AWSやGCP、CloudflareなどのAPI Gateway層)でもしっかり監視の網を張り巡らせる必要があります。

ここで重要になるのが、「異常なトークン消費を検知したときのリアルタイム・アラート」です。

監視設計で見るべき3つの指標

1. 1リクエストあたりの最大トークン数(入力・出力双方)

  • 通常のユーザーが送らないような巨大な値(例: 5,000トークン以上など)を閾値(しきいち)に設定し、それを超えた瞬間にセキュリティ担当者のSlackやPagerDutyに通知が飛ぶようにします。

2. 特定ユーザー(IPアドレスやAPIキー単位)からの総消費量(1時間あたり)

  • 短時間に何十回もギリギリの長文を送りつけてくる「地道な嫌がらせ(スロー・ポイズン攻撃)」を検知するため、累積の消費量をトラッキングします。

3. AIプロバイダーからのエラーレート(429や5xx系)の急増

  • もし自分たちの防衛網をすり抜けてAPI側でパンクが起きた場合、いち早く気づけるように全体のトラフィック状況をダッシュボード(DatadogやCloudWatchなど)で常時可視化しておきましょう。

> 💡 現場のプロからのアドバイス
> 「とりあえず全部ブロックすればいいや」と制限を厳しくしすぎると、今度は「普通のユーザーが真面目に長文の質問をしただけでエラーになる」という悲しい事態(誤検知)が起きちゃいます。
> 自社サービスのユースケース(カスタマーサポートなのか、長文の要約ツールなのか)に合わせて、「普通の人は絶対に使わないライン」をデータで見極めながら閾値をチューニングしていくことが、腕の見せ所であり、一番泥臭くて大切な作業になります。

—

まとめ

生成AIのセキュリティ対策は、これまでのWebセキュリティの常識がそのまま通用しないからこそ、難しくもあり、エンジニアとしての醍醐味でもあります。

  • AIへの攻撃は「トークン(言葉のパーツ)」の過剰消費という形でやってくる
  • 入口(アプリケーション層)でトークン数を予測・見積もりし、大きすぎるものは 429 で弾く
  • インフラ側でも消費量を常に監視し、異常があれば即座にアラートを飛ばせる仕組みを作る

最初は難しく感じるかもしれませんが、要は「我が家の防犯カメラと頑丈なドアを新しくする」のと同じです。一歩ずつ、できることから確実に実装を重ねて、安全で安心なAIサービスを一緒に育て上げていきましょう!

コメント

タイトルとURLをコピーしました