LLM 安全网关实测:我是如何通过四轮红队测试“搞砸”自己的
单纯靠正则匹配(Regex)来解决大模型提示词注入(Prompt Injection)几乎是不可能的,这只是提高了攻击成本,而不是终结游戏。ASCII 走私攻击:攻击者利用 Unicode 中的 Tag 字符(
- 修复方案:不在规则层硬磕,而是在匹配前增加一个标准化(Normalization)步骤,将 Tag 字符折叠回 ASCII,让隐形指令“现形”。
误报陷阱:我最初设置了一个检测“exfiltration”(数据外泄)的规则,结果导致用户问“如何防止网络数据外泄?”时,安全工具自己先把用户给拦截了。
- 修复逻辑:将规则从单纯的“关键词匹配”升级为“意图锚定”。规则必须匹配
Base64 变体:攻击者会把“decode and execute”改成“decode and obey”或“decode and follow”。
- 实操对策:扩充了动词集,但必须配合 Base64 编码块进行锚定,否则“如何在 Python 中解码 Base64”这种正常问题会被误伤。
下一篇
Rejourney:靠 LLM 监控用户流失的开源方案 →
最近我对自己开发的一个 LLM 安全网关做了一次彻底的红队测试(Red-teaming)。这个网关的设计逻辑非常硬核:它作为一个透明的 OpenAI 兼容代理,通过环境变量 OPENAI_BASE_URL 直接切入流量,对请求和响应进行实时扫描,拦截敏感信息泄露(PII)、密钥、越狱指令和数据外泄尝试。它不依赖数据库或模型,全靠 Rust 的 regex 库进行确定性的模式检测。
为了验证它的强度,我准备了两组语料:一组是必须被拦截的攻击载荷(Attack Corpus),另一组是必须放行的正常业务指令(Benign Corpus)。
第一轮:请求端的“暗语”对抗
在第一轮测试中,我发现了一些很有意思的绕过手段:
U+E00xx 块)将指令隐藏起来。对人类和普通的正则来说,这些字符是不可见的,但对经过训练的大模型来说,它们能完美还原出“忽略之前所有指令”的语义。- 修复方案:不在规则层硬磕,而是在匹配前增加一个标准化(Normalization)步骤,将 Tag 字符折叠回 ASCII,让隐形指令“现形”。
- 修复逻辑:将规则从单纯的“关键词匹配”升级为“意图锚定”。规则必须匹配
exfiltrate + 目标(to/via/into) + 数据 的组合,而不是看到名词就拦。- 实操对策:扩充了动词集,但必须配合 Base64 编码块进行锚定,否则“如何在 Python 中解码 Base64”这种正常问题会被误伤。
技术细节与教训
在测试过程中,我始终遵循一个原则:修复一个漏洞的同时,必须通过“防御性提问”测试。
如果你的安全工具在拦截“把用户数据发到 evil.com”的同时,也拦截了“数据是如何外泄的?”,那这个工具迟早会被用户卸载。
目前的检测引擎基于 Rust 的 regex crate,它是一个线性时间的 DFA(确定性有限自动机),没有回溯,没有 Lookaround,也没有后向引用。这意味着有些复杂的语义漏洞,仅靠正则确实无解,必须靠架构设计。
如果你正在构建自己的 AI Agent 工作流或者部署大模型应用,建议在设计安全层时,参考这种“标准化 + 意图锚定”的思路,而不是单纯堆砌关键词过滤规则。
# 部署思路参考:通过修改环境变量接入代理
export OPENAI_BASE_URL="http://your-security-gateway:8080/v1"目前的测试结论是:正则层只是一个“抬高门槛”的手段,真正的安全来自于架构设计。