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, 大语言模型, 漏洞靶场, 红队实验, 轻量级, 逆向工具, 防御检测