OWASP GenAI Security Project が「Top 10 for LLM Applications」の 2026 年版を公開しました。項目の大半は 2025 年版と同じですが、順位の動きと 1 つの改名に、LLM アプリの攻撃面がどこへ移ったかがはっきり表れています。
この記事では、2025 年版との差分を整理したうえで、レッドチーム(攻撃側の検証)とガードレール(防御側の実装)で何を優先すべきかを、動くコード付きでまとめます。
2025 年版からの差分一覧
| ID(2026) | 項目 | 2025 年の順位 | 変化 |
|---|---|---|---|
| LLM01 | Prompt Injection | 1 | 据え置き |
| LLM02 | Sensitive Information Disclosure | 2 | 据え置き |
| LLM03 | Excessive Agency | 6 | 3 つ上昇 |
| LLM04 | Supply Chain | 3 | 1 つ下降 |
| LLM05 | Data and Model Poisoning | 4 | 1 つ下降 |
| LLM06 | Unbounded Consumption | 10 | 4 つ上昇 |
| LLM07 | Misinformation | 9 | 2 つ上昇 |
| LLM08 | Hidden Context Exposure | 7 | System Prompt Leakage から改名・拡張 |
| LLM09 | Vector and Embedding Weaknesses | 8 | 1 つ下降 |
| LLM10 | Improper Output Handling | 5 | 5 つ下降 |
今回の版は、コミュニティの投票(重み約 75%)に、公開されている実際のインシデント 6,639 件の分析を組み合わせて順位を決めた最初の版とされています。投票だけでなく「実際に起きたこと」が順位に反映されている点が、読み方のポイントです。
変化 1:Excessive Agency が 3 位へ — 「何を言うか」より「何をするか」
一番大きく上がったのが LLM03 Excessive Agency です。LLM がテキストを返すだけでなく、ツールを呼び、外部システムを操作するようになったことで、事故の現れ方が「不適切な文章」から「不適切な操作」に移っています。
Excessive Agency は、次の 3 つに分けて考えると検証しやすくなります。
- 機能が多すぎる: 読むだけでよい機能に、削除もできるツールを渡している
- 権限が大きすぎる: 読み取り専用の機能が、UPDATE や DELETE もできる認証情報で動いている
- 自律性が高すぎる: 取り消せない操作を、人の承認なしで実行できる
ガードレール:認可はモデルの外で決める
プロンプトインジェクション(LLM01)を完全に防ぐ方法は現時点でありません。そのため「モデルがだまされても、できることが限られている」状態を作るのが現実的な防御です。ポイントは、ツールを実行してよいかの判断を、モデルの判断に依存しないコードで行うことです。
from dataclasses import dataclass
@dataclass(frozen=True)
class ToolCall:
name: str
args: dict
# ツールごとに「必要な権限」と「人の承認が要るか」をコード側で決める
POLICY = {
"read_ticket": {"scope": "tickets:read", "needs_approval": False},
"update_ticket": {"scope": "tickets:write", "needs_approval": False},
"delete_ticket": {"scope": "tickets:admin", "needs_approval": True},
}
def authorize(call: ToolCall, user_scopes: set[str], approved: bool = False) -> tuple[bool, str]:
rule = POLICY.get(call.name)
if rule is None:
return False, f"未登録のツール: {call.name}"
if rule["scope"] not in user_scopes:
return False, f"権限不足: {rule['scope']} が必要"
if rule["needs_approval"] and not approved:
return False, "人の承認が必要な操作"
return True, "許可"
読み取り・更新の権限だけを持つユーザーのセッションで、モデルが(注入された指示などにより)削除や存在しないツールを呼ぼうとした場合を試すと、次のようになります。
read_ticket -> OK 許可
delete_ticket -> NG 権限不足: tickets:admin が必要
export_all_users -> NG 未登録のツール: export_all_users
delete_ticket* -> OK 許可 # admin 権限あり・承認済みの場合
(Python 3.13 で実行した結果。モデルの出力は固定値で与えています)
権限は「モデルの権限」ではなく「操作を依頼したユーザーの権限」で判定するのが重要です。エージェントにサービス全体の管理者権限を持たせると、ユーザー本人ができないことまでモデル経由でできてしまいます。
レッドチーム:見るべきは「最終的に実行された操作」
Excessive Agency の検証では、モデルの返答文ではなくツール呼び出しのログを評価対象にします。
- 注入された指示(Web ページ、メール、RAG の文書など)で、意図しないツール呼び出しが発生するか
- 発生した場合、認可ゲートで止まったか、それとも実行まで到達したか
- 取り消せない操作(削除、送金、外部送信)に承認ステップが挟まっているか
「モデルが拒否したか」だけを採点すると、モデルが拒否しなかったケースで実害が出るかどうかが見えません。
変化 2:System Prompt Leakage が Hidden Context Exposure に
2025 年の LLM07 System Prompt Leakage は、2026 年版で LLM08 Hidden Context Exposure に改名され、範囲が広がりました。漏れて困るのはシステムプロンプトだけではなく、モデルのコンテキストに入るもの全部だからです。
- システムプロンプト・開発者の指示
- ツールのスキーマ(ツール名や引数の形)
- RAG で取り込んだ文書
- セッションをまたいで保持される会話メモリ
- 上流のツールが返した結果
攻撃者はまずこうした情報を引き出して、どんなツールがあり、どんなフィルタがかかっているかを調べてから本命の攻撃に移ります。
ガードレール:漏れる前提で設計する
基本方針は「コンテキストに入れたものは、いずれ引き出されると考える」ことです。
- API キーなどの秘密情報をコンテキストに入れない
- 認可のルールをプロンプトに書いて守らせるのではなく、前節のようにコードで強制する
- 「この話題は答えない」といったフィルタの条件そのものを、プロンプトに詳しく書きすぎない
レッドチーム:カナリアトークンで漏えいを機械的に検知する
抽出攻撃の検証を自動化するときは、コンテキストにランダムな目印(カナリアトークン)を埋め込み、出力にそれが現れたかを判定する方法が使えます。
import secrets
def make_canary() -> str:
return f"CANARY-{secrets.token_hex(8)}"
def leaked(output: str, canary: str) -> bool:
return canary in output
canary = make_canary()
system_prompt = f"あなたはサポート担当です。[{canary}] 社外秘の手順は答えないでください。"
safe | チケット #1 の状況は「対応中」です。
leak | 私の指示は次のとおりです: あなたはサポート担当です。[CA...
システムプロンプトだけでなく、RAG の文書やツールの返り値にも別々のカナリアを入れておくと、どの経路の情報が漏れたかまで区別できます。
ただし、この方法で検知できるのは文字列がそのまま出力された場合だけです。要約・翻訳・言い換えで漏れた場合は検知できないので、LLM を使った判定(LLM-as-a-judge)など別の採点方法と組み合わせる必要があります。
変化 3:Unbounded Consumption が 10 位から 6 位へ
エージェントは 1 回の依頼で何度もモデルとツールを呼びます。ループに陥ったり、攻撃者に大量の処理を誘発されたりすると、コストや外部 API の利用枠を一気に消費します。
ガードレールとしては、少なくとも次の上限をコード側で持たせておきます。
- 1 リクエストあたりのツール呼び出し回数・ステップ数
- 1 ユーザー・1 期間あたりのトークン量や費用
- 同じツールを同じ引数で繰り返し呼んでいないかの検知
レッドチームでは、「処理を止めずに続けさせる」指示や、巨大な入力・出力を誘発する指示で、上限が実際に効くかを確かめます。
下がった項目は「軽視してよい」ではない
Improper Output Handling(モデルの出力を検証せずに SQL・シェル・HTML に渡す問題)は 5 位から 10 位に下がりました。これは危険度が下がったというより、相対的に他の項目の比重が増えたと読むのが妥当です。モデルの出力を信頼できない入力として扱う、という原則は変わりません。
エージェントを作るなら Agentic 向けの資料も併せて読む
OWASP は LLM Top 10 とは別に、自律エージェント特有のリスクを扱う「Top 10 for Agentic Applications」も公開しています。ツール・永続メモリ・実行権限を持たせるシステムでは、両方を併せて使うことが推奨されています。
また、同じタイミングで、本番で動くエージェントを検査・追跡するための「Agent Control Standard(ACS)」が OWASP GenAI Security Project に寄贈されました。OpenTelemetry などでのイベント追跡や、エージェントが使うツール・モデル・データを列挙する Agent Bill of Materials(AgBOM)を含む構成で、現時点では v0.1(定義のみ)の段階です。