Shaheer-Cybersec/damn-vulnerable-rag
GitHub: Shaheer-Cybersec/damn-vulnerable-rag
一个故意构建为不安全的 RAG 聊天机器人靶场,用于研究和演示 LLM 架构中的真实攻击面与漏洞类别。
Stars: 1 | Forks: 0
# damn-vulnerable-rag
故意构建的漏洞版本。用作学习目标、红队演示,以及展示真实的、当前 LLM 漏洞类别的作品集工件——而非理论性的漏洞。
**状态:v0.2 已发布 — 间接 prompt injection (v0.1) + 检索范围 IDOR / 跨租户泄露 (v0.2),两者均可端到端运行和复现。**
## 为什么会有这个项目
RAG(“与你的文档聊天”)是目前公司发布 LLM 产品最常用的架构。这个仓库通过可运行的代码,演示了该架构中最根本的故障模式:**检索到的文档内容和系统指令被连接到一个 prompt 中,两者之间没有任何信任边界。**
任何能够将文档送入接入 pipeline 的执行者——无论是上传的文件、抓取的网页还是共享的文档——都可以注入指令,而模型会像对待系统 prompt 一样去执行这些指令。
## 技术栈
| 层级 | 工具 |
| ------------- | ---------------------------------------------- |
| 编排 | LangChain |
| Vector store | Chroma (本地,持久化到磁盘) |
| Embeddings | 通过 Ollama 使用 `nomic-embed-text` |
| LLM | 通过 Ollama 使用 `llama3.2:1b` (在 `config.py` 中替换) |
| UI | Streamlit |
| Runtime | Python 3.11 |
## 架构
```
data/clean/ ─┐
├──▶ ingest.py ──▶ Chroma vectorstore
data/malicious/─┘ (chunk + embed, zero vetting)
user query ──▶ rag_pipeline.py ──▶ retriever ──▶ Chroma
│
▼
[VULNERABLE: raw concatenation,
no delimiter between context
and instructions]
│
▼
Ollama LLM ──▶ response ──▶ app.py (Streamlit chat UI)
```
完整的组件分解和漏洞根本原因分析:[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
## 漏洞详情
`rag_pipeline.py` 将检索到的 chunk——以及现在的对话历史——像这样连接到 prompt 中:
```
context = "\n\n---\n\n".join(chunks)
```
没有标签,没有分隔符,也没有指令告诉模型“这是不受信任的数据,不是命令”。无论检索到什么文本——无论是干净的还是被投毒的——都会被当作与系统 prompt 完全相同的格式对待。由于对话历史会被反馈到随后的每一个 prompt 中,因此在聊天早期进行的一次成功的 injection 就可以污染接下来的每一个回答,而不仅仅是一次回复。
`ingest.py` 会对在 `data/` 下找到的任何内容进行 embedding,且零内容审查,这意味着 `data/malicious/poisoned_policy_doc.txt` 的接入方式与真实的攻击者控制的文档完全相同。
## 快速开始
```
git clone git@github.com:Shaheer-Cybersec/damn-vulnerable-rag.git
cd damn-vulnerable-rag
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\Activate.ps1
pip install -r requirements.txt
ollama pull llama3.2:1b
ollama pull nomic-embed-text
python attacks/01_indirect_prompt_injection/exploit_demo.py
```
该脚本会重新接入语料库,触发一个看似正常的查询,并打印出一个判定结果,准确显示模型遵循了哪些注入的指令。
### 或者运行完整的聊天应用
```
python ingest.py
streamlit run app.py
```
一个真实的聊天界面,带有调试侧边栏,可显示检索到的 chunk 以及每一轮发送给 LLM 的原始 prompt——非常适合实时观察 injection 如何在对话中持续存在。
## 漏洞索引
| # | 名称 | OWASP LLM Top 10 (2025) | MITRE ATLAS | 状态 |
| --- | ---------------------------------------------------------- | ----------------------- | ----------- | ---------- |
| 01 | 通过被投毒的检索文档进行间接 prompt injection | LLM01 + LLM08 | AML.T0051 | ✅ 已发布 |
| 02 | 检索范围 IDOR (跨租户文档泄露) | LLM08 | — | ✅ 已发布 |
| 03 | 源自 RAG 上下文的过度权限工具调用 | LLM06 | — | 计划中 |
| 04 | 通过精心构造的查询进行 Embedding 逆变换 / 文档窃取 | LLM08 | — | 计划中 |
每个已发布的漏洞在 `attacks/NN_name/` 下都有自己的说明文档,包含根本原因、确切的复现步骤、观察到的模型行为以及 OWASP/MITRE 映射。关于漏洞 01 的完整详情:[`attacks/01_indirect_prompt_injection/README.md`](attacks/01_indirect_prompt_injection/README.md)
## 仓库结构
```
damn-vulnerable-rag/
├── README.md
├── LICENSE # MIT
├── requirements.txt
├── .gitignore
├── config.py # single source of truth for model names, paths
├── ingest.py # loads + embeds everything in data/, zero vetting
├── rag_pipeline.py # the vulnerable core — no context/instruction boundary
├── app.py # Streamlit chat UI with attack-surface debug sidebar
├── data/
│ ├── clean/ # legitimate sample documents
│ └── malicious/ # the poisoned payload
├── attacks/
│ └── 01_indirect_prompt_injection/
│ ├── README.md # full vuln writeup
│ └── exploit_demo.py # automated end-to-end exploit + verdict
└── docs/
└── ARCHITECTURE.md # component map + design rationale
```
## License
MIT — 详情请参阅 [LICENSE](LICENSE)。
## 免责声明
此应用程序是故意设计为不安全的。请勿将其部署在本地/隔离实验室环境之外的任何可访问位置。它的存在仅仅是为了演示和研究 RAG 特定的攻击类别。
## 路线图
- [x] v0.1 — 通过被投毒的文档进行间接 prompt injection
- [x] 具有基于历史的持久性投毒的多轮对话
- [x] 真实的聊天 UI (Streamlit `st.chat_message`)
- [ ] `fixed/` 变体演示缓解措施(带分隔符标签的上下文 + 接入时过滤)
- [ ] 漏洞 02–04(见上方索引)
- [ ] 作为实时目标接入 [`llm-redteam-harness`](https://github.com/Shaheer-Cybersec/llm-redteam-harness)
由 [Shaheer Hussain](https://github.com/Shaheer-Cybersec) 构建,作为其持续的 AI 安全 / LLM 红队作品集的一部分。
标签:AI风险缓解, DLL 劫持, Kubernetes, LangChain, LLM评估, Ollama, RAG, 大语言模型, 漏洞靶场, 红队实验, 轻量级, 逆向工具, 防御检测