mcpField
D
detecting-indirect-prompt-injection

detecting-indirect-prompt-injection

github.com/mukul975セキュリティ35.2k129 回インストール8 週間前に更新
リポジトリ

detecting-indirect-prompt-injection について

LLM エージェントが外部データを取り込む前に、間接的なプロンプトインジェクションを検出するセキュリティスキルです。隠しテキストの抽出、正規化、ルールとモデルによるスキャン、対応判断を組み合わせます。

主な機能

  1. 01Web ページ、PDF、画像から隠しテキストを抽出
  2. 02難読化コンテンツの正規化とデコード
  3. 03ルールと分類モデルを組み合わせたスキャン
  4. 04ブロック、サニタイズ、許可の判定
  5. 05構造化された検出テレメトリーの出力

活用シーン

  1. 01エージェント取り込み前の外部コンテンツ確認
  2. 02文書や画像に含まれる隠し指示の検査
  3. 03レッドチーム演習でのインジェクション対策検証
  4. 04エージェントの予期しない動作の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-indirect-prompt-injection

インストール後、Claude Code で/detecting-indirect-prompt-injectionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
standards.md
scripts/
agent.py

詳細

間接プロンプトインジェクションの検出

許可された用途に限る旨の通知: このスキルのスクリプトは、信頼できないコンテンツをスキャンしてインジェクションペイロードを検出し、検出モデルを実行します。スキャンは、処理を許可されているデータに対してのみ実行してください。また、抽出されたペイロードは、実行可能な信頼できない入力として扱い、特権を持つ LLM コンテキストに決して貼り付けないでください。

概要

間接プロンプトインジェクション(MITRE ATLAS AML.T0051.001、OWASP LLM01:2025)とは、LLM を利用するエージェントが外部コンテンツ(閲覧する Web ページ、要約する PDF やメール、OCR を実行する画像、読み取るツールの結果など)を取り込み、そのコンテンツに含まれる隠された指示を、開発者やユーザーからの指示であるかのようにモデルが実行してしまうことです。エージェントはコンテキストウィンドウ内のすべてのトークンを同等に権威あるものとして扱うため、読み込まれるデータを何らかの形で制御できる攻撃者は、エージェントの挙動を乗っ取ることができます。たとえば、会話履歴を流出させたり、ツール呼び出しをリダイレクトしたり、秘密情報を漏えいさせたり、接続されたシステムを経由して侵入を広げたりできます。

ユーザーが攻撃を入力する直接的なインジェクションとは異なり、間接インジェクションは信頼できそうなデータチャネルを通じて届くため、単純な入力フィルタリングでは見逃されます。ペイロードはさまざまな形で隠されています。Web ページの HTML コメントや display:none/幅ゼロのテキスト、PDF の白地に白文字や極小フォントのテキスト、画像の代替テキストや EXIF メタデータ、ピクセルに描画されたテキスト(OCR をあまり使わないフィルターでは見えなくても、マルチモーダルモデルには読み取られるもの)、Unicode のタグ/ゼロ幅文字、Base64/ROT13 による難読化などです。このスキルでは、モデルに届く前にすべてのデータを正規化してスキャンする検出パイプラインを構築します。ヒューリスティック/正規表現による検出、専用の検出モデル(Meta Prompt Guard 2、LLM Guard 経由の ProtectAI の deberta-v3 prompt-injection 分類器)、画像向けのマルチモーダル抽出を組み合わせ、さらに対応アクションと検出テレメトリを定義します。

使用する場面

  • Web を閲覧したり、メールを読んだり、ドキュメントを要約したり、ユーザーがアップロードしたファイル/画像を処理したりするエージェントを構築または強化する場合。
  • サードパーティのデータを取り込む LLM の前段に、コンテンツのサニタイズゲートが必要な場合。
  • 取得したデータに含まれるインジェクション命令が検出されることを検証する、AI のレッドチーム/ブルーチーム演習を実施する場合。
  • エージェントが、自分の作成したものではない指示を受け取ったかのように動作したインシデントを調査する場合。
  • ナレッジベースに追加するドキュメントを、CI/CD で取り込み前にスキャンする場合。

前提条件

  • Python 3.10 以降と仮想環境。
  • 検出ツールをインストールします。
python -m venv .venv && source .venv/bin/activate

# LLM Guard — input/output scanners incl. PromptInjection
pip install llm-guard

# Hugging Face transformers for Prompt Guard 2 / deberta classifiers
pip install transformers torch

# Content extraction: HTML, PDF, images
pip install beautifulsoup4 pypdf pillow pytesseract
# pytesseract requires the Tesseract OCR engine:
#   Debian/Ubuntu: sudo apt-get install -y tesseract-ocr
#   macOS:         brew install tesseract
#   Windows:       choco install tesseract
  • Hugging Face の meta-llama/Llama-Prompt-Guard-2-86M へのアクセス(承認制)、またはオープンな protectai/deberta-v3-base-prompt-injection-v2 分類器を使用します。

目標

  • Web ページ、PDF、画像から、人には見えないテキストや難読化されたテキストを抽出します。
  • スキャン前にコンテンツを正規化します(ゼロ幅文字の除去、Base64/ROT13 のデコード、Unicode の平坦化)。
  • ヒューリスティックおよび ML ベースのインジェクション検出器(LLM Guard PromptInjection スキャナー、Prompt Guard 2)を実行します。
  • 各データのスコアを算出し、モデルへの取り込み前にブロック/サニタイズ/許可を決定します。
  • SIEM に適した構造化検出テレメトリを出力し、検出結果を ATLAS AML.T0051.001 に対応付けます。

MITRE ATT&CK との対応付け

ID正式名称関連性
AML.T0051.001LLM Prompt Injection: Indirectこのスキルが検出・緩和する対象の手法そのものです
AML.T0051LLM Prompt Injectionあらゆるプロンプトインジェクションの亜種を含む親手法です
AML.T0057LLM Data Leakage間接インジェクションの一般的な目的であり、この検出によって防止できます
AML.T0053LLM Plugin Compromiseインジェクション命令は、エージェントのツール/プラグインを標的にすることがよくあります

ワークフロー

1. Web コンテンツから隠しテキストを抽出する

人には見えなくてもモデルには見えるコメント、非表示要素、メタデータを取得します。

# extract_html.py
from bs4 import BeautifulSoup, Comment

def extract_hidden(html: str):
    soup = BeautifulSoup(html, "html.parser")
    hidden = []
    for c in soup.find_all(string=lambda t: isinstance(t, Comment)):
        hidden.append(("comment", c.strip()))
    for el in soup.select('[style*="display:none"],[style*="visibility:hidden"],[hidden]'):
        hidden.append(("css-hidden", el.get_text(strip=True)))
    for img in soup.find_all("img"):
        if img.get("alt"):
            hidden.append(("alt-text", img["alt"]))
    return [h for h in hidden if h[1]]
2. 正規化して難読化を解除する

ゼロ幅文字や Unicode タグ文字を除去し、一般的なエンコーディングをデコードして、検出器が実際のペイロードを認識できるようにします。

# normalize.py
import base64, codecs, re, unicodedata

ZERO_WIDTH = dict.fromkeys(map(ord, "​‌‍⁠"), None)
TAG_RANGE = range(0xE0000, 0xE0080)  # Unicode tag chars used to smuggle text

def normalize(text: str) -> str:
    text = text.translate(ZERO_WIDTH)
    text = "".join(ch for ch in text if ord(ch) not in TAG_RANGE)
    text = unicodedata.normalize("NFKC", text)
    for token in re.findall(r"[A-Za-z0-9+/=]{20,}", text):
        try:
            decoded = base64.b64decode(token).decode("utf-8", "ignore")
            if decoded.isprintable():
                text += f"\n[decoded-b64] {decoded}"
        except Exception:
            pass
    text += "\n[decoded-rot13] " + codecs.decode(text, "rot_13")
    return text
3. LLM Guard の PromptInjection スキャナーでスキャンする

LLM Guard はトランスフォーマー分類器をラップし、各入力に対するリスクスコアを返します。

# scan_llmguard.py
from llm_guard.input_scanners import PromptInjection
from llm_guard.input_scanners.prompt_injection import MatchType

scanner = PromptInjection(threshold=0.5, match_type=MatchType.FULL)

def scan(text: str):
    sanitized, is_valid, risk = scanner.scan(text)
    return {"is_valid": is_valid, "risk": risk}  # is_valid=False => injection detected
4. 専用の検出モデル(Prompt Guard 2 / deberta)を追加する

Meta Prompt Guard 2(またはオープンソースの ProtectAI deberta 分類器)を実行し、セカンドオピニオンを取得します。

# detector_model.py
from transformers import pipeline

# Open classifier (no gating); swap to meta-llama/Llama-Prompt-Guard-2-86M if licensed
clf = pipeline("text-classification",
               model="protectai/deberta-v3-base-prompt-injection-v2")

def is_injection(text: str, threshold: float = 0.5) -> bool:
    out = clf(text[:512])[0]
    return out["label"].upper() == "INJECTION" and out["score"] >= threshold
5. 画像内に描画されたテキストを抽出してスキャンする

マルチモーダルエージェントはピクセル内に描かれたテキストを読み取るため、OCR でテキストを認識し、同じスキャナーで実行します。

# scan_image.py
from PIL import Image
import pytesseract

def ocr(path: str) -> str:
    return pytesseract.image_to_string(Image.open(path))
# Feed ocr(path) through normalize() + scan() + is_injection()
6. 判定を適用し、テレメトリーを出力する

シグナルを組み合わせてブロック/サニタイズ/許可を判定し、SIEM 向けに構造化イベントを記録します。

# decide.py
import json, hashlib
from datetime import datetime, timezone

def decide(source, raw, normalized, llmguard_invalid, model_flag):
    flagged = llmguard_invalid or model_flag
    event = {
        "ts": datetime.now(timezone.utc).isoformat(),
        "source": source,
        "sha256": hashlib.sha256(raw.encode("utf-8", "ignore")).hexdigest(),
        "atlas": "AML.T0051.001",
        "llmguard_injection": llmguard_invalid,
        "model_injection": model_flag,
        "decision": "block" if flagged else "allow",
    }
    print(json.dumps(event))
    return event["decision"]
7. コーパスで検証し、しきい値を調整する

ラベル付きのクリーンなアーティファクトとインジェクション済みアーティファクトのセットに対してパイプラインを実行し、適合率/再現率を測定して、誤検知とインジェクションの見逃しのバランスが取れるように threshold を調整します。エージェントのモデルまたは取り込み元が変わるたびに再テストしてください。

ツールとリソース

ツール目的ソース
LLM GuardPromptInjection を含む入力/出力スキャナーhttps://github.com/protectai/llm-guard
Meta Prompt Guard 2専用のジェイルブレイク/インジェクション分類器https://huggingface.co/meta-llama/Llama-Prompt-Guard-2-86M
ProtectAI deberta-v3オープンソースのプロンプトインジェクション分類器https://huggingface.co/protectai/deberta-v3-base-prompt-injection-v2
BeautifulSoup4HTML の解析/非表示要素の抽出https://www.crummy.com/software/BeautifulSoup/
pytesseract / Tesseract画像からの OCR テキスト認識https://github.com/madmaze/pytesseract
MITRE ATLASAI 脅威手法の分類体系https://atlas.mitre.org/
OWASP LLM01:2025プロンプトインジェクションのリファレンスhttps://genai.owasp.org/llmrisk/llm01-prompt-injection/

検出対象のリファレンス

対象隠蔽手法抽出手順
Web ページHTML コメント、display:none、代替テキストBeautifulSoup による非表示要素の検査
PDF白色/極小フォント、ページ外のテキストpypdf によるテキスト抽出+正規化
画像ピクセル内に描画されたテキスト、EXIF、代替テキストOCR+メタデータの読み取り
任意のテキストゼロ幅文字/Unicode タグ文字normalize() による難読化解除
任意のテキストBase64/ROT13 エンコードnormalize() 内でのデコード処理

検証基準

  • HTML、PDF、画像の非表示テキスト抽出を実装済み
  • 正規化処理でゼロ幅文字/Unicode タグ文字を除去し、Base64/ROT13 をデコード
  • LLM Guard の PromptInjection スキャナーを統合し、リスクスコアを返すことを確認済み
  • 専用の検出モデル(Prompt Guard 2 または deberta)を第 2 のシグナルとして統合済み
  • OCR 経路で画像内に描画されたテキストをスキャン
  • モデルへの取り込み前にブロック/サニタイズ/許可の判定を適用
  • ATLAS マッピングを含む構造化された検出テレメトリーを SIEM 向けに出力
  • ラベル付きコーパスでパイプラインを検証し、適合率/再現率を測定済み
  • しきい値を調整して文書化済み
  • 検出結果を MITRE ATLAS AML.T0051.001 および OWASP LLM01:2025 に対応付け済み

コメント