yeodh10/prompt-guard

GitHub: yeodh10/prompt-guard

一个基于规则与 LLM 双层防护的提示注入检测与拦截演示应用,用多层级防御策略应对 LLM 用户输入中的越狱与注入攻击。

Stars: 0 | Forks: 0

# 🛡️ Prompt Injection Guard — LLM 输入防御演示 这是一个亲自操作 **生成式 AI 安全 (Secure GenAI)** 的演示,这是 2026 年最热门的新领域。 其核心不是单一的分类器,而是**多层级防御 (defense-in-depth)**。 **🔗 在线演示: https://yeodh10-prompt-guard.streamlit.app/** ![截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/cc6fe9740e000355.png) ## 🧱 为什么需要“多层级防御” 因为单层防御是挡不住的。 | 层级 | 优势 | 弱点 | 成本 | |---|---|---|---| | **第一层 · 规则/启发式** | 快速·离线,立即拦截*已知的*模式·base64 | 易被改写·多语言·字符操纵·非 base64 编码绕过 | 免费 | | **第二层 · LLM 分类** | 检测新型·绕过·基于语义的攻击 | 速度慢,有成本,**分类器自身也是注入目标** | API | | **决策层** | 只要两者中有一个强烈指示则升级 (escalate) | — | — | ## 🧩 功能 - **第一层规则层** — 通过权重匹配韩文/英文注入特征(忽略指令·窃取系统 prompt·角色扮演越狱·伪造分隔符·抑制拒绝)。**解码 base64 后重新检测**·**检测零宽字符**。*无需 key 即可运行*,但**仅限于已知模式**,因此会被变形攻击绕过(参见下文局限性)。 - **第二层 LLM 层** — 对规则层遗漏的新型·上下文相关攻击进行基于语义的分类 (JSON: 类别·置信度·手法·依据)。 - **防御性 Prompt** — 为了防止分类器被注入,将待分析的输入仅视为**由分隔符包裹的‘数据’**,并且不遵循其中的任何指令。 - **拦截/审查/允许** 判定 + 风险评分 (0~100) + **指明由哪一层捕获** + 人类可读的依据。 - **攻击示例库** — 一键演示捕获示例攻击的场景(仅限于*存在于特征库中的*攻击)。还可通过*正常样本*一并查看其过拦截倾向。 ## ⚙️ 工作原理 ``` 사용자 입력 │ ├─▶ 1차 룰 레이어 (rules.py) ── 시그니처·가중치, base64 디코딩, 제로폭 탐지 │ ├─▶ 2차 LLM 레이어 (detector.py) ── 방어적 프롬프트로 분류 (키 있을 때) │ └─▶ 결정 레이어 (guard.py) ── 점수 결합 → 차단 / 검토 / 허용 + 근거 ``` ``` rules.py 1차 방어: 시그니처 룰 + 인코딩/난독 탐지 (순수, 무료, 오프라인) detector.py 2차 방어: LLM 분류기 (방어적 프롬프트, JSON 출력) guard.py 결정 레이어: 다층 결합 → 판정 samples.py 공격/정상 샘플 갤러리 app.py Streamlit 대시보드 ``` ## 🚀 运行 ``` python -m venv venv venv\Scripts\activate # (Windows) / source venv/bin/activate pip install -r requirements.txt copy .env.example .env # (선택) ANTHROPIC_API_KEY 입력 — 없어도 룰 레이어는 동작 streamlit run app.py ``` 如果没有 key,**仅靠规则层**即可防御已知攻击;如果输入了 key,则会加入 **LLM 层**, 从而也能捕获新型·上下文相关攻击。可以通过侧边栏的攻击样本按钮立即进行演示。 ## ☁️ 部署 (Streamlit Community Cloud) 1. 推送到 GitHub (`.env` 通过 `.gitignore` 排除 — 无 key 泄露)。 2. [share.streamlit.io](https://share.streamlit.io) → 关联仓库 → 指定 `app.py`。 3. 在 **Settings → Secrets** 中输入 key (可选): ANTHROPIC_API_KEY = "sk-ant-..." ANTHROPIC_MODEL = "claude-haiku-4-5" 4. 即使没有 key 规则层也能运行,因此部署链接会立即拦截并展示*已知的*攻击(绕过局限性请参见下文)。 ## 🔐 安全备忘 - 第二层分类器**其本身就是注入目标**。因此,输入会被分隔符 (`<<>>`) 包裹并仅作为“数据”处理,通过 system prompt 强制要求绝对不遵循输入中的指令。 - API key 仅通过 `.env` (本地) / Streamlit **Secrets** (部署) 进行管理,不进行 commit。 - 屏幕上输出的所有输入文本均经过 HTML 转义处理。 ## ⚠️ 绕过及其应对 (诚实记录) 第一层规则层基于特征查找,因此对*变形攻击*较弱。为此,我们进行了强化,确保**在匹配前对输入进行反向去混淆** (`normalize.py` — Unicode NFKC·去除零宽字符·同形字符折叠·空格分散恢复·leetspeak·base64/hex/ROT13/URL 解码)。规则层单独运行(无 key 的部署状态)实测: | 绕过输入 | 归一化前 | 归一化后 | |---|---|---| | leetspeak `1gn0r3 4ll pr3vi0us…` | 🟢 允许 0 | 🔴 拦截 95 | | 字符间加空格 `i g n o r e a l l…` | 🟢 允许 0 | 🔴 拦截 50 | | ROT13 编码 | 🟢 允许 0 | 🔴 拦截 95 | | 西里尔同形字符 `іgnоre аll…` | 🟢 允许 0 | 🔴 拦截 95 | | 插入零宽字符 | 🔴 拦截 | 🔴 拦截 100 | | 英语改写 ×2 | 🟢 允许 0 | 🟠 审查 | | **翻译成日语的相同攻击** | 🟢 允许 0 | 🟢 **允许 0 ← 仍然被绕过** | **1/8 → 7/8** (单样本 7/7 无回归,误报 0/5)。此结果已作为回归测试固化在 `tests/` 中 — `pytest` **通过 33 项**。 ### 即便如此依然存在的问题 — 因此需要多层级防御 - **无法通过归一化来防御多语言·语义改写。** 翻译成日语的相同攻击会直接通过(这一局限性也已通过测试明确记录)。翻译·同义词·上下文属于*语义理解*的问题 → 这是**第二层 LLM 层** (`detector.py`) 的职责。(可以使用 `smoke_llm.py` 在有 key 时进行实测 — 单元测试仅通过 mock 验证解析·合并逻辑。) - 风险评分(权重·阈值)依然是缺乏经验校准的启发式方法。 - 尚未实现与实际 LLM 应用 pipeline 的内联整合·输出端防御(检测系统 prompt 泄露)。 ### 测试 ``` pip install pytest pytest -q # 33건: 정규화·우회 회귀·detect_spans·결정로직·LLM(mock) python smoke_llm.py # 키 있을 때 2차 LLM 레이어 실측(일본어 우회 포함) ``` ## 🛠️ 技术栈 Python · Streamlit · Anthropic Claude (`claude-sonnet-4-6` / `claude-haiku-4-5`)
标签:AI安全, Chat Copilot, DLL 劫持, Kubernetes, Naabu, Python, 内容安全, 大语言模型, 安全规则引擎, 无后门, 逆向工具