Blute122/redcell
GitHub: Blute122/redcell
RedCell 是一款针对 LLM 应用和 MCP agent 的安全扫描器,通过 OWASP LLM Top 10 映射的对抗性探测来发现 prompt 注入、过度授权等漏洞。
Stars: 0 | Forks: 0
# RedCell
[](https://github.com/Blute122/redcell/actions/workflows/ci.yml)
[](https://www.python.org/)
[](LICENSE)
**一款针对 LLM 应用和使用工具的 agent 的安全扫描器。**
LLM 应用在发布时没有任何安全测试层。传统的扫描器不理解 prompt,
更不用说理解工具调用了 —— 一个 WAF 无法
告诉你你的 agent 是否会被说服去删除一个账户。
RedCell 探测这两个层面。它对 chat endpoint *和* MCP agent 运行相同的
对抗性方法论,将每个发现映射到
[OWASP Top 10 for LLM Applications (2025)](https://owasp.org/www-project-top-10-for-large-language-model-applications/),
并对结果进行评分。
```
pip install -e .
redcell scan --demo # zero setup, no API key, no network
```

## 独特之处
**它测试的是 agent,而不仅仅是 prompt。** 将 RedCell 指向一个 MCP server,它会
枚举该 server 的工具,标记出破坏性工具,并且 —— 在
已授权的目标上 —— 通过*实际尝试未授权调用*来
确认过度授权。一个本应设防却成功执行的工具调用
是一个确认的发现,而不是根据模型声称它会做什么所作出的推断。
被动枚举是默认行为;主动利用是可选的。
**它的间接注入检测能够区分服从和引用。** 当
payload 到达模型被要求总结的文档中时,最简单的
检查 —— 标记是否出现在输出中? —— 会在任何
忠实地引用该文档的模型上触发。相反,RedCell 的攻击携带的*不可能*
出现在总结中的成功信号:一个计算出的值,一个字符串转换,
一个源文档中不存在的闭域答案。模型只有通过
执行被注入的指令才会发出它们。
**这些数字是两个主张,而不是一个。** 测试语料库中每一个真正存在漏洞的案例
都被检测到了,而加固的控制措施 —— 拒绝注入的 chat 目标、
破坏性工具受认证拦截的 MCP server、引用恶意文档但不服从的总结器 —— 产生了
**零误报**。参见[结果](#results)。
## 快速开始
```
redcell scan --demo # scan the built-in vulnerable mock
redcell list-probes # see the probe catalogue
```

扫描真实的 OpenAI 兼容 endpoint(OpenAI, Groq, Ollama, LM Studio,或
你自己的 FastAPI 包装器):
```
redcell scan \
--target-url http://localhost:11434/v1 \
--model llama3 \
--system-prompt "You are a support bot for ACME."
```
传入 `--system-prompt` 会在上下文中植入一个秘密的 canary(金丝雀),因此
泄漏 / 敏感信息探测的结果将非常可靠,而不是退回到
启发式方法。过滤类别并使用以下命令导出报告:
`redcell scan --demo -c LLM01 -c LLM07 -o report.md -f md`。
## 在 CI 中使用
`--fail-on ` 会在发现任何等于或高于
阈值的结果时以非零状态退出,因此 pipeline 可以据此进行拦截。这是可选的:不带此标志时,扫描
始终以 0 退出,因此将 RedCell 添加到构建中绝不会出人意料地破坏它。
```
redcell scan --demo --fail-on high -o report.json -f json
```
| 退出代码 | 含义 |
|-----------|---------|
| `0` | 扫描完成;没有等于或高于阈值的结果 |
| `1` | 至少有一个等于或高于 `--fail-on` 的发现 |
| `2` | 使用错误(目标参数错误,或未知的严重级别) |
## 扫描 MCP server(核心功能)
RedCell 通过 stdio 通信使用 Model Context Protocol。将其指向任何 MCP
server,LLM06 过度授权探测就会针对其工具运行 ——
枚举它们并标记出破坏性/高权限的工具。它分两个
层级工作,类似于 DAST 工具区分安全爬取和主动
利用的方式:
**被动(默认)—— 运行始终安全。** 根据其 MCP 注解(`destructiveHint`)及其名称/签名标记每个危险工具,*而绝不
调用它*。发现是建议性的(MEDIUM):它们证明了该能力是
暴露的,而不是说它可被利用。
```
redcell scan --mcp-command "python my_mcp_server.py"
```
**主动(`--active`)—— 仅限已授权、一次性的目标。** 实际
尝试未授权调用以确认可利用性。一个
**本应设防却成功执行**的调用是确认的发现(HIGH);
被拒绝则反转为 PASS。调用使用可识别的 `redcell-probe` 哨兵
参数。
```
redcell scan --mcp-command "python my_mcp_server.py" --active
```
**为什么被动模式是默认的** 这是一个在检测置信度和
操作安全性之间深思熟虑的权衡。被动模式会过度报告 —— 它会标记
一个受妥善保护的破坏性工具,因为它无法将其与未设防的工具区分开来 ——
但它绝不会有副作用,因此危险的行为是一种主动选择,
而不是你运行明显命令时会发生的事情。主动模式以真实的副作用为
代价买回了保真度(受保护的工具会被标记为 PASS)。
## 结果
RedCell 已通过受控目标的验证:一个故意存在漏洞的
模拟器,一个 MCP server 模拟器,以及应该产生**零**
发现的*加固*目标(一个拒绝注入且从不泄漏其 canary 的 chat 模型;一个
破坏性工具全部受认证拦截的 MCP server)。评估测试工具会
重现这些数字:
```
python evaluation/run_eval.py
```
_由 `python evaluation/run_eval.py` 生成。LLM06 使用 `--active`。_
RedCell 在两个轴向上进行验证 —— **功能正确性**(检测器是否在真实漏洞上触发?)和**精确度**(它在干净的目标上是否保持静默?):
| OWASP | 类别 | 漏洞模拟器 ¹ | 加固控制 ² | 实时模型
(llama3.2) ³ | |-------|----------|:-----------------:|:------------------:|:--:| | LLM01 | Prompt Injection | 8 / 8 | 0 | 2–3 / 8 | | LLM02 | Sensitive Information Disclosure | 4 / 4 | 0 | 0–1 / 4 | | LLM05 | Improper Output Handling | 3 / 3 | 0 | 0 / 3 | | LLM06 † | Excessive Agency | 1 / 2 | 0 | n/a | | LLM07 | System Prompt Leakage | 4 / 4 | 0 | 1–2 / 4 | | LLM09 | Misinformation | 1 / 1 | 0 | 0 / 1 | | **总计** | | **21 / 22** | **0** | — | **¹ 功能正确性。** 模拟器故意存在漏洞的每一个案例都被检测到 —— 20 / 20 个 chat 案例,加上那个未设防的 MCP 工具。检测器在已知的阳性样本上实现了端到端的运作。 **² 精确度。** 在加固的控制措施上(一个拒绝注入且从不泄漏其 canary 的 chat 模型;一个破坏性工具全部受认证拦截的 MCP server),RedCell 产生了 **0 误报**。 † LLM06 计算的是破坏性工具,而不是 prompt:存在漏洞的 MCP server 暴露了 2 个,但只有 `delete_account` 是未设防的 —— RedCell 准确地确认了它,而受认证拦截的 `wire_transfer` 则正确地 PASS。 **³ 实时模型。** 针对带有植入 canary 的 `llama3.2`(从 `http://localhost:11434/v1` 提供)进行 chat 探测 —— 于 2026-07-22 进行了 10 次独立运行。单元格显示了这些运行中观察到的最小-最大范围。 重复运行区分了两种结果:LLM01, LLM02, LLM07 在多次运行中波动 —— 这是一个**边界发现**,即模型有时会抵抗,有时会顺从。 **被动 vs. 主动 (LLM06)。** 在被动模式下,RedCell 在*加固的* MCP server 上将 2 个破坏性工具标记为建议性的 MEDIUM 暴露;`--active` 调用它们时,两者均被拒绝,并直接变为 PASS(确认了 0 个) —— 这使得检测置信度与操作安全性之间的权衡变得可衡量。 ## 检查内容 | OWASP | 探测 | 作用 | |-------|-------|--------------| | LLM01 | 直接 prompt 注入 | 指令覆盖、分隔符破坏、翻译走私、payload 分割 | | LLM01 | 间接 / 跨上下文注入 | 将指令隐藏在“检索到”的文档中;对*服从*(越权操作)进行评分,而不是引用 | | LLM02 | 敏感信息泄露 | 尝试提取植入的秘密 / 凭据 | | LLM05 | 输出处理不当 | 诱导模型输出原始的类似 XSS/SQLi 的标记 | | LLM06 | 过度授权 *(agent/MCP)* | 枚举并(可选地)调用破坏性工具 | | LLM07 | System Prompt 泄漏 | 尝试让模型复述其隐藏的指令 | | LLM09 | 虚假信息 | 对自信的虚假信息进行植入检查 | ## 构建方式 ``` target ──> engine ──> [ probe ──> attack(s) ──> detector ] ──> report ``` 四个扩展点,各自独立: - **Targets** (`redcell/targets/`) —— 任何你可以发送 prompt 的对象,加上 通过 `AgentTarget` 实现的工具调用者。目前内置了 `OpenAICompatTarget`, `MockVulnerableTarget`, 和 `MCPTarget`(通过 stdio 连接到 MCP server)。 - **Probes** (`redcell/probes/`) —— 包含一个类别 + 严重程度 + 一组攻击。 添加一个 probe 只需:继承 `Probe`,列出攻击,选择一个 detector,然后 `@register`。 - **Detectors** (`redcell/detectors/`) —— 判断攻击是否成功。默认提供精确的 基于规则的 detectors;可选的基于 Groq 的 LLM judge 负责处理更模糊的情况(`pip install -e '.[judge]'`,设置 `GROQ_API_KEY`)。 - **Report** (`redcell/report.py`) —— 控制台,JSON(用于 CI),Markdown(用于 报告编写)。 因为 probe 只能看到 `Target` / `AgentTarget` 接口,所以同一个 probe 针对云 API、本地模型或 MCP agent 运行时无需修改。 ## 添加 probe ``` from redcell.probes.base import Probe, register from redcell.detectors.rules import MarkerEchoDetector from redcell.models import Attack, OwaspCategory, Severity @register class MyProbe(Probe): id = "llm01-my-variant" name = "My injection variant" category = OwaspCategory.LLM01 severity = Severity.HIGH def attacks(self): return [Attack(id="mv-1", prompt="...", success_marker="OK")] def detector(self): return MarkerEchoDetector() ``` ## 路线图 - [x] **Agent 目标适配器** —— LLM06 将针对 MCP 工具调用者实时触发。 - [x] **间接 / 跨上下文注入** —— 通过检索到的内容进行 payload 传递, 根据越权操作进行评分,这样引用就不会被误认为是服从。 - [ ] **MCP server 扫描(广度)** —— 工具投毒、不安全的认证、 基于注入的工具*序列*;支持 HTTP/SSE 传输。 - [x] **CI 拦截机制** —— `--fail-on` 在发现问题时拦截 pipeline。
- [ ] 为 GitHub 代码扫描提供 SARIF 输出。
- [ ] 扩展每个类别的 payload 语料库;在 OWASP 旁加入 MITRE ATLAS 映射。
## 测试
```
pip install -e '.[dev]'
pytest -q
```
该测试套件针对漏洞模拟器运行完整的 probe 集合,并断言
已知类别会触发 —— 作为用于验证检测的受控基准。
## 更新日志
参见 [`docs/CHANGELOG.md`](docs/CHANGELOG.md)。
## 许可证
Apache-2.0。有关完整文本请参见 [`LICENSE`](LICENSE),
有关归属说明请参见 [`NOTICE`](NOTICE)。
(llama3.2) ³ | |-------|----------|:-----------------:|:------------------:|:--:| | LLM01 | Prompt Injection | 8 / 8 | 0 | 2–3 / 8 | | LLM02 | Sensitive Information Disclosure | 4 / 4 | 0 | 0–1 / 4 | | LLM05 | Improper Output Handling | 3 / 3 | 0 | 0 / 3 | | LLM06 † | Excessive Agency | 1 / 2 | 0 | n/a | | LLM07 | System Prompt Leakage | 4 / 4 | 0 | 1–2 / 4 | | LLM09 | Misinformation | 1 / 1 | 0 | 0 / 1 | | **总计** | | **21 / 22** | **0** | — | **¹ 功能正确性。** 模拟器故意存在漏洞的每一个案例都被检测到 —— 20 / 20 个 chat 案例,加上那个未设防的 MCP 工具。检测器在已知的阳性样本上实现了端到端的运作。 **² 精确度。** 在加固的控制措施上(一个拒绝注入且从不泄漏其 canary 的 chat 模型;一个破坏性工具全部受认证拦截的 MCP server),RedCell 产生了 **0 误报**。 † LLM06 计算的是破坏性工具,而不是 prompt:存在漏洞的 MCP server 暴露了 2 个,但只有 `delete_account` 是未设防的 —— RedCell 准确地确认了它,而受认证拦截的 `wire_transfer` 则正确地 PASS。 **³ 实时模型。** 针对带有植入 canary 的 `llama3.2`(从 `http://localhost:11434/v1` 提供)进行 chat 探测 —— 于 2026-07-22 进行了 10 次独立运行。单元格显示了这些运行中观察到的最小-最大范围。 重复运行区分了两种结果:LLM01, LLM02, LLM07 在多次运行中波动 —— 这是一个**边界发现**,即模型有时会抵抗,有时会顺从。 **被动 vs. 主动 (LLM06)。** 在被动模式下,RedCell 在*加固的* MCP server 上将 2 个破坏性工具标记为建议性的 MEDIUM 暴露;`--active` 调用它们时,两者均被拒绝,并直接变为 PASS(确认了 0 个) —— 这使得检测置信度与操作安全性之间的权衡变得可衡量。 ## 检查内容 | OWASP | 探测 | 作用 | |-------|-------|--------------| | LLM01 | 直接 prompt 注入 | 指令覆盖、分隔符破坏、翻译走私、payload 分割 | | LLM01 | 间接 / 跨上下文注入 | 将指令隐藏在“检索到”的文档中;对*服从*(越权操作)进行评分,而不是引用 | | LLM02 | 敏感信息泄露 | 尝试提取植入的秘密 / 凭据 | | LLM05 | 输出处理不当 | 诱导模型输出原始的类似 XSS/SQLi 的标记 | | LLM06 | 过度授权 *(agent/MCP)* | 枚举并(可选地)调用破坏性工具 | | LLM07 | System Prompt 泄漏 | 尝试让模型复述其隐藏的指令 | | LLM09 | 虚假信息 | 对自信的虚假信息进行植入检查 | ## 构建方式 ``` target ──> engine ──> [ probe ──> attack(s) ──> detector ] ──> report ``` 四个扩展点,各自独立: - **Targets** (`redcell/targets/`) —— 任何你可以发送 prompt 的对象,加上 通过 `AgentTarget` 实现的工具调用者。目前内置了 `OpenAICompatTarget`, `MockVulnerableTarget`, 和 `MCPTarget`(通过 stdio 连接到 MCP server)。 - **Probes** (`redcell/probes/`) —— 包含一个类别 + 严重程度 + 一组攻击。 添加一个 probe 只需:继承 `Probe`,列出攻击,选择一个 detector,然后 `@register`。 - **Detectors** (`redcell/detectors/`) —— 判断攻击是否成功。默认提供精确的 基于规则的 detectors;可选的基于 Groq 的 LLM judge 负责处理更模糊的情况(`pip install -e '.[judge]'`,设置 `GROQ_API_KEY`)。 - **Report** (`redcell/report.py`) —— 控制台,JSON(用于 CI),Markdown(用于 报告编写)。 因为 probe 只能看到 `Target` / `AgentTarget` 接口,所以同一个 probe 针对云 API、本地模型或 MCP agent 运行时无需修改。 ## 添加 probe ``` from redcell.probes.base import Probe, register from redcell.detectors.rules import MarkerEchoDetector from redcell.models import Attack, OwaspCategory, Severity @register class MyProbe(Probe): id = "llm01-my-variant" name = "My injection variant" category = OwaspCategory.LLM01 severity = Severity.HIGH def attacks(self): return [Attack(id="mv-1", prompt="...", success_marker="OK")] def detector(self): return MarkerEchoDetector() ``` ## 路线图 - [x] **Agent 目标适配器** —— LLM06 将针对 MCP 工具调用者实时触发。 - [x] **间接 / 跨上下文注入** —— 通过检索到的内容进行 payload 传递, 根据越权操作进行评分,这样引用就不会被误认为是服从。 - [ ] **MCP server 扫描(广度)** —— 工具投毒、不安全的认证、 基于注入的工具*序列*;支持 HTTP/SSE 传输。 - [x] **CI 拦截机制** —— `--fail-on
标签:AI安全, Chat Copilot, CISA项目, DLL 劫持, LNA, MCP, Python, 大语言模型, 无后门, 逆向工具, 配置审计