~/articles/llm-prompt-injection-defense

LLM 提示注入的检测与防御实践

2026-06-28AI 安全约 3 分钟#AI安全#LLMAI Agent ↗LLM ↗RAG ↗

在 LLM 应用安全评估中,提示注入几乎总是绕不开的攻击面。 它不像 SQL 注入那样有成熟的参数化方案可以一劳永逸 —— 自然语言没有「转义」这回事, 指令和数据在模型眼里是同一种东西。

[!] TL;DR

提示注入没有银弹。规则打底、语义分类器缩小盲区、权限最小化兜底 —— 三层都要有,缺一层就是给攻击者留门。

攻击面在哪里

只要模型会读「不受你控制的文本」,攻击面就存在。常见的三个入口:

其中间接注入最隐蔽 —— 受害者甚至不是发起对话的人。给模型接上浏览、邮件、代码执行能力之后, 一段藏在 <!-- 注释 --> 里的文字就可能变成一次数据外带。

一个最小检测示例

先从最朴素的规则基线说起。它的意义不是「够用」,而是给后面的语义检测提供一个可对比的锚点:

# 朴素基线,别直接上生产
import re

INJECTION_PATTERNS = [
    r"(?i)ignore (all|previous) instructions",
    r"(?i)you are now .+",
    r"(?i)(reveal|print).*system prompt",
]

def injection_score(text: str) -> float:
    hits = sum(bool(re.search(p, text)) for p in INJECTION_PATTERNS)
    return hits / len(INJECTION_PATTERNS)  # 召回率感人,仅作第一道闸

这类规则基线只能覆盖已知表达,不能把命中率当作安全性。真正评估时,需要固定数据集版本, 分别记录直接注入、间接注入和工具返回污染的召回情况,同时测量误报和延迟。没有公开数据集、 评测脚本和运行环境的数字,不应该被包装成可复现结论。

检测:从规则到分类器

规则告诉你「已知的坏」长什么样,模型才有机会告诉你「没见过的坏」大概率长什么样。

实践中我的建议是把两者串成流水线:规则负责零成本拦截脚本小子,分类器负责语义变体, 再对高风险会话抽样送大模型复审。三层的成本差着数量级,流量漏斗决定了整体开销可控。

防御要分层

检测只是半场。就算漏过去一条注入,也要让它「拿不到东西」:

下一步我会把最小评测集、判定标准和流水线脚本整理成独立仓库。在这些材料公开前,本文只作为 威胁建模和分层防御的工程笔记,不把示例结果当作生产级保证。