mcpField
D
detecting-indirect-prompt-injection

detecting-indirect-prompt-injection

github.com/mukul975安全35.2k129 次安装8 周前更新
代码仓库

关于 detecting-indirect-prompt-injection

用于在 LLM Agent 读取外部数据前检测间接提示注入的安全技能,结合隐藏文本提取、内容规范化、规则与模型扫描,并支持后续处置。

主要功能

  1. 01提取网页、PDF 和图像中的隐藏文本
  2. 02规范化并解码混淆内容
  3. 03结合规则与分类模型扫描
  4. 04选择拦截、清理或放行
  5. 05生成结构化检测遥测

适用场景

  1. 01在 Agent 读取前筛查第三方内容
  2. 02检查文档和图像中的隐藏指令
  3. 03在红队演练中验证注入防护
  4. 04调查 Agent 行为异常

安装

复制下面的命令,在终端中运行。

$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 驱动的 Agent 摄入外部内容时 —— 它浏览的网页、它摘要的 PDF 或电子邮件、它进行 OCR 的图像、它读取的工具结果 —— 而该内容包含隐藏指令,模型随后会像这些指令来自开发者或用户一样执行它们。由于 Agent 将其上下文窗口中的所有 token 视为同等权威,攻击者只要控制任何被消费的产物,就能劫持 Agent 的行为:窃取对话历史、重定向工具调用、泄露机密,或通过已连接的系统进行横向移动。

与直接注入(用户输入攻击内容)不同,间接注入通过看似可信的数据通道到达,这就是为什么简单的输入过滤会漏掉它。载荷以多种形式隐藏:网页中的 HTML 注释和 display:none/零宽文本,PDF 中的白底白字或微小字体文本,图像中的 alt 文本和 EXIF 元数据,渲染为像素的文本(对轻度 OCR 过滤不可见,但会被多模态模型读取),Unicode 标签字符/零宽字符,以及 Base64/ROT13 混淆。本技能构建了一条检测流水线,在产物到达模型之前对其规范化并扫描,结合启发式/正则检测、专用检测器模型(Meta Prompt Guard 2、通过 LLM Guard 使用的 ProtectAI deberta-v3 prompt-injection 分类器),以及针对图像的多模态提取,然后定义响应操作和检测遥测。

何时使用

  • 在构建或加固会浏览网页、读取电子邮件、摘要文档或处理用户上传文件/图像的 Agent 时。
  • 当你需要在摄入第三方数据的 LLM 前面设置内容净化关卡时。
  • 在 AI 红队/蓝队演练期间,验证检索产物中注入的指令能否被捕获。
  • 在调查 Agent 表现得像收到了并非你编写的指令的事件时。
  • 作为对添加到知识库的文档进行 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 分类器。

目标

  • 从网页、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注入的指令经常以 Agent 的工具/插件为目标

工作流

1. 从网页内容中提取隐藏文本

提取人类永远看不到但模型会看到的注释、隐藏元素和元数据。

# 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 封装了一个 transformer 分类器,并针对每个输入返回一个风险评分。

# 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. 提取并扫描图像中渲染的文本

多模态 Agent 会读取绘制在像素中的文本;对其执行 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. 强制执行决策并发出遥测数据

将各信号合并为 block / sanitize / allow,并为 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 以在误报与漏检注入之间取得平衡。每当 Agent 的模型或数据摄取来源发生变化时,都要重新测试。

工具与资源

工具用途来源
LLM Guard输入/输出扫描器,包括 PromptInjectionhttps://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/

检测面参考

检测面隐藏技术提取步骤
网页HTML 注释、display:none、alt 文本BeautifulSoup 隐藏元素处理
PDF白色/微小字体、页面外文本pypdf 文本提取 + 归一化
图像渲染像素、EXIF、alt 文本OCR + 元数据读取
任意文本零宽 / Unicode 标签字符normalize() 去混淆
任意文本Base64 / ROT13 编码normalize() 中的解码处理

验证标准

  • 已为 HTML、PDF 和图像实现隐藏文本提取
  • 归一化会剥离零宽/Unicode 标签字符并解码 Base64/ROT13
  • 已集成 LLM Guard PromptInjection 扫描器并返回风险评分
  • 已集成专用检测模型(Prompt Guard 2 或 deberta)作为第二信号
  • OCR 路径可扫描图像中渲染的文本
  • 在模型摄取之前强制执行 block/sanitize/allow 决策
  • 为 SIEM 发出带 ATLAS 映射的结构化检测遥测数据
  • 已在带标签的语料库上验证流水线并测量精确率/召回率
  • 阈值已调整并记录成文档
  • 发现结果已映射到 MITRE ATLAS AML.T0051.001 和 OWASP LLM01:2025

评论

支持 Markdown