gigioneggiando/argo
GitHub: gigioneggiando/argo
Argo 是一款基于大语言模型的静态代码漏洞检测工具,通过模拟人类审计员阅读源码并配合对抗性验证来发现安全缺陷,无需编写规则即可生成可审查的漏洞报告。
Stars: 3 | Forks: 0
# 👁️ Argo — LLM 原生的静态漏洞检测
Argo 通过驱动 LLM 担任分析师来发现**源代码**中的安全漏洞——它像人类审计员那样阅读代码,而不是将规则与图进行匹配。将它指向任何代码库——**本地文件夹**、私有 repo 或公共 repo——它就能生成可供审查的漏洞报告。其核心理念是:从可重用的通用 prompt 出发,并利用特定于目标的上下文(技术栈、endpoint、文档、公告历史)**自动对其进行增强**——从而确保每次审计都使用量身定制的 prompt,而非通用版本。它可以在你手头的任何工具上运行:**Claude Code**、**Codex CLI** (OpenAI),或是**本地开源模型**。
**定位。** Argo 是一款 **LLM 原生的 SAST**——是基于规则的静态分析器(如 CodeQL、Semgrep)的补充与替代方案:无需编写任何内容(无需编写查询或规则包),并且它能捕捉固定模式所遗漏的逻辑/授权缺陷——代价是它是*概率性*的,而非穷尽的(参见[设计决策](docs/design-decisions.md))。它**在设计上就是静态的**——它从不执行目标(这是一条硬性约束),因此它*不是* DAST、fuzzer 或符号执行器。
**漏洞赏金(Bug-bounty)分类是一种专用模式**(包括范围/参与规则(RoE)摄取、提交草稿、跨运行的重提交追踪),而不是该工具的全部——请参阅[两种模式](#-two-modes-general-audit-and-bug-bounty)。
- 🔎 **威胁感知审计** — 可选的 Stage-0 互联网开源情报(OSINT)收集(CVE、安全公告、历史记录)为侦察提供数据。
- 🧠 **原型驱动的 prompt** — 对软件进行分类,然后为其编写自定义审计 prompt。
- 🛡️ **对抗性验证** — 在每个发现被确认保留之前,由第二个模型尝试*反驳*它。
- 🔌 **多后端** — Claude / Codex / OpenAI / 本地开源模型,使用同一套 pipeline(参见 [docs/backends.md](docs/backends.md))。
- 🩹 **自愿启用的修复** — 为每个发现提出补丁建议,并在隔离副本上**验证其能否成功编译**。
- 💬 **审问式对话** — 结合完整上下文询问*“为什么你没有发现 X?”*([实战示例](docs/chat-example.md))。
- 📊 **基准测试与成本** — 准确率/召回率测试套件 + 观察到的成本分析。
- 🚫 **仅检测,只读,绝不实时** — 约束在代码层面强制执行,而不仅仅停留在 prompt 层面。

## 🪪 两种模式:通用审计与漏洞赏金
Argo 在**相同**的五阶段引擎上以两种模式运行:
| | **通用代码审计**(默认) | **漏洞赏金分类** |
|---|---|---|
| **输入** | 文件夹或 repo — **无摘要** | 项目摘要 (`--brief`) + 链接 + repo |
| **范围** | 仅限源码,从代码中合成(零 token 摄取) | 从摘要中解析(资产、RoE、排除项) |
| **适用** | 你自己的/私人的代码、OSS 审查、CTF、研究 | 具有安全豁免(safe harbor)的有范围限制的项目 |
| **额外功能** | — | 提交草稿、范围过滤、跨运行的重提交追踪 |
审计你自己的代码是最常见的情况:省略 `--brief`,将 `--repo` 指向**本地文件夹**,该 repo 将以只读方式挂载,且绝不会被推送到任何地方(本地 / OSS 模型会将源码完全保留在设备上;云端后端会将其发送到相应的 API 进行分析)。漏洞赏金模式则在此基础之上增加了针对特定项目的辅助架构。
## 🔒 原则与限制(请先阅读此部分)
Argo 用于**已授权的**安全审查——你自己的代码、具有安全豁免条款的漏洞赏金项目、CTF 或研究。三项约束在编排器中强制执行,而不是仅仅交由 prompt 来控制:
1. **绝不自动提交。** pipeline 在草稿生成处停止;提交始终由人类执行。
2. **绝不联系活跃主机**,即使对于 `source_and_live` 目标也是如此。分析是在源代码上静态进行的。对于活跃目标,验证步骤仅作为由你自行运行的文本计划存在,且必须在项目规则范围内进行(禁止 DoS,禁止扫描)。这种纯静态立场是*刻意设计的*,也是让 Argo 保持在 SAST 而非 DAST 范畴的原因。
3. **在每次会话中均保持 repo 只读:** pipeline 绝不会修补任何内容。
此外,范围中声明的禁止技术(例如“禁止 DoS”)会被传播到每一个生成的 prompt 中,如果缺失这些内容,prompt 渲染将会失败(如果模型对其进行了改写,则会被逐字重新插入——参见[防护栏](docs/guardrails.md))。
## 🧩 资产文件(可重用的核心)
安全逻辑存在于 prompt 中;编排器只是将它们串联起来的粘合剂。
| 文件 | 作用 |
|---|---|
| `00_recon_synthesis_meta_prompt.md` | 阶段 2。对 repo 进行特征画像,将其与范围进行核对,并**生成**互补的自定义 prompt。这是从通用到详细增强的发生地。 |
| `01_audit_prompt_template.md.j2` | 每个生成的 prompt 都必须遵循的 Jinja 骨架。固定部分(角色、发现格式、交战规则、反误报约束)永不改变;`{{ }}` 插槽承载特定于目标的内容。 |
| `02_adversarial_validation_prompt.md` | 阶段 4。对于每一个发现,它会开启一个全新的上下文并试图**推翻它**。只有幸存下来的发现才会被提升为最终结果。 |
| `scope_schema.json` | 范围/规则的结构。作为每个阶段和最终发现过滤器的权威输入。 |
| `findings_schema.json` | 规范化的发现格式,用于去重和验证。 |
| `BUILD_SPEC.md` | 用于指导编程智能体围绕这些资产构建编排器的规范。 |
## ✨ 增强机制如何工作(阶段 2)
这是设计的核心。三件事物汇聚在一起——可重用的资产(始终相同)、包含你的链接和规则的 `scope.json`,以及 repo 侦察结果(技术栈、endpoint、CVE 历史)——随后输出专用于那一次扫描的互补的自定义 prompt。

这种划分是**原型驱动的**:阶段 2 首先对目标软件的类型进行分类(Web/API、CMS、插件/扩展、库/SDK、CLI、Agent/LLM、移动端、数据/ML pipeline 等),并选择最适合的 prompt 划分方式——通常是 3 个互补的 prompt,且始终包含一个以架构为主导的全系统 prompt——而不是固定的 Web 应用拆分方式。有关 prompt 生成器的工作原理以及如何安全地对其进行修改,请参见 [docs/prompt-synthesis.md](docs/prompt-synthesis.md)。
## 🗂️ 项目布局
```
argo/
cli.py
models.py # pydantic models for scope + findings
runner.py # AgentRunner interface (Claude headless · Codex · mock)
stages/{ingest,research,recon,audit,validate,report}.py
research.py·fixes.py·verify.py·benchmark.py·chat.py·costs.py·archetype.py
prompts/ # the assets, version-controlled in git
ledger.py # SQLite findings + cost ledger
server/ · webapp/ # HTTP API + no-build web UI
runs// # scope.json, repo/, repo_profile.json, prompts/, findings/, REPORT.md
```
## 📥 输入:如何设置项目(漏洞赏金模式)
针对每个项目,有三个独立的东西会分别存放在三个不同的位置。
- **项目描述** -> 通过 `--brief` 传递的文本文件。从平台粘贴整个项目页面(范围、规则、奖励、排除项、“禁止 DoS”)。
- **有用的链接**(站点、文档、安全页面、公告历史) -> 一个文本文件,**每行一个**,通过 `--links` 传递。这些不是代码。
- **代码仓库**(例如官方 GitHub) -> **不是链接**,它是待分析的代码库,通过 `--repo` 传递。
助记法:如果它是 Agent 必须**阅读以理解**的内容(站点、文档、公告) -> 放入 `links.txt`。如果它是 Agent 必须**分析**的内容(代码) -> 使用 `--repo`。
示例。项目文件夹:
`brief.md`
```
ACME CMS — Bug Bounty Program
Scope: app.acme.com, api.acme.com, the acme/acme-cms repository
Out of scope: *.staging.acme.com, third-party plugins
Rules: no DoS / volumetric testing, no social engineering, max 10 req/s on live
Rewards: Critical $$$, High $$, ...
```
`links.txt`
```
https://acme.com
https://docs.acme.com
https://acme.com/security
https://acme.com/security/advisories
```
运行:
```
argo ingest --brief brief.md --links links.txt --repo https://github.com/acme/acme-cms
```
生成的 `scope.json`:
```
{
"program_name": "ACME CMS",
"program_brief_raw": "",
"in_scope": [{ "asset": "acme/acme-cms", "type": "source_repo" }],
"out_of_scope": ["*.staging.acme.com", "third-party plugins"],
"prohibited_techniques": ["no DoS / volumetric", "no social engineering", "max 10 req/s live"],
"reference_links": ["https://acme.com", "https://docs.acme.com", "https://acme.com/security", "https://acme.com/security/advisories"]
}
```
阶段 2 会提取 `reference_links` 并将它们注入到每个自定义 prompt 的顶部,这样 prompt 在一开始就已经知道去哪里阅读文档和公告了。
## ⚡ 用法
```
argo ingest --brief BRIEF --links LINKS --repo PATH_OR_URL # Stage 1
argo recon --run RUN_ID # Stage 2
argo run --run RUN_ID # Stage 3
argo validate --run RUN_ID # Stage 4
argo report --run RUN_ID # Stage 5
argo pipeline --brief ... --links ... --repo ... # 1-5, stops before submission
argo pipeline --repo ./my-code # 🔐 local/personal review — NO brief, NO URL
```
**想要审计你自己的 / 私有的本地代码?** 省略 `--brief` 并将 `--repo` 指向**本地文件夹**(它不需要是 git repo,并且**绝不会被推送到任何地方**——该 repo 以只读方式挂载)。
Argo 会从该文件夹合成一个最小的**仅限源代码**的范围(零 token 摄取,Web 调查自动关闭)并进行审计。请注意分析过程本身:**云端后端**(Claude / Codex)会将源码发送到该提供商的 API 进行分析——只有**本地 / OSS 模型**(`--codex-oss`)才能将所有内容**完全保留在本地设备上**。
选择一个后端(默认 `headless` = Claude Code):
```
argo pipeline ... --runner codex # Codex CLI / OpenAI
argo pipeline ... --runner codex --codex-oss --codex-local-provider ollama --codex-model qwen2.5-coder:32b
```
低成本模式:
```
argo pipeline ... --runner mock # exercises the whole glue with fixtures, zero tokens
argo pipeline ... --dry-run # runs ingest+recon, shows generated prompts, then STOPS
argo pipeline ... --no-research # skip the Stage-0 web OSINT (fully offline)
```
`--dry-run` 是一个用于反馈 prompt 质量的循环:它允许你在付费运行它们之前先目测检查这些自定义 prompt。
## 🖥️ Web UI
一个无需构建步骤的 Web 界面(粘贴项目信息,指向 repo,实时观看 argo 运行,阅读结果,然后与分析过程进行对话)位于 `webapp/` 目录中,并由 API 提供服务。最简单的方法:**双击 `start.cmd`**(Windows)或运行 `./start.sh`。或者:
```
python -m argo.cli serve --open # starts + opens http://127.0.0.1:8000
```
它默认使用免费的 **mock** 运行器;从高级面板中切换到真实运行(设置预算)。请参阅 [docs/ui.md](docs/ui.md) 和 [docs/api.md](docs/api.md)。
## 🔬 各阶段详情
**1 — 摄取。** 将摘要解析为 `scope.json`,并根据 `scope_schema.json` 进行验证。如果该项目禁止自动化,则会引发一个标志,禁止整个运行过程中的任何实时交互。将 repo 克隆/复制到运行目录中,设为只读。
**0 — 调查** *(默认开启,可选择性关闭,这是唯一一个联网的阶段)*。根据摘要、链接和项目名称,它会执行**公共 Web OSINT**(CVE、安全公告、项目的安全历史),并生成 `research_brief.md` + `threat_intel.json`,注入到侦察阶段,以便审计是针对威胁定制的。绝不触碰项目范围内活跃的主机;`--no-research` 可保持运行完全处于离线状态。
**2 — 侦察与合成。** 在拥有 repo 读取权限的情况下运行 `00_recon_synthesis_meta_prompt.md`。生成 `repo_profile.json`、互补的自定义 prompt(符合模板规范),以及 `synthesis_notes.md`。
**3 — 审计。** 对于每个 prompt,都会在一个隔离的工作目录中开启一个独立的 agent 会话,repo 保持只读。每个会话输出经过 `findings_schema.json` 验证的 JSON 格式发现。不同的关注点可以并行运行。
**4 — 验证。** 合并发现结果,计算 `dedup_key = sha1(normalize(file + line + cwe))` 并折叠重复项。对于每个幸存的发现,在全新的上下文中运行 `02_adversarial_validation_prompt.md`。丢弃 `out_of_scope` 和被 `refuted`(反驳)的结果;保留 `confirmed`(已确认)和需要 `needs_runtime_verification`(运行时验证)的结果。
**5 — 报告。** 生成 `REPORT.md`(摘要、按已验证的严重程度和置信度排序的发现结果、“优先修复”排序、残留的未知问题),并为每个确认的发现生成一份草稿(DRAFT)提交。将每个发现追加到 SQLite 账本中。
## 📦 产物捕获
**文件是事实来源**,清单只是一个索引。每个 Claude 会话会将其产物作为单独的文件写入其专属的临时目录中(`repo_profile.json`、每个 prompt 对应一个 `.md` 文件、`SECURITY_FINDINGS__.json`、验证裁定),且每个文件都符合对应的 schema。最终消息会返回一个小型的清单用于索引它们。编排器将文件视为权威来源;如果清单丢失或会话中断,它会回退到使用通配符匹配临时目录(部分恢复)。Claude Code 的 `--output-format json` 仅用于获取运行元数据(会话 ID、成本、停止原因),从不用于产物。
原因:深度审计的发现结果和完整的 prompt 太大,如果不冒着被截断的风险,就无法容纳在单个 stdout JSON 中(截断会悄无声息地丢弃发现);文件能够挺过长时间的会话崩溃,并且清晰地映射到异构的产物类型。
## 🔌 后端与模型策略
**后端。** 同一套 pipeline,可替换的引擎——选择你手头可用的:
`--runner headless`(Claude Code) · `--runner codex`(Codex CLI → OpenAI,或者加上 `--codex-oss --codex-local-provider ollama|lmstudio` 来运行 **本地开源** 模型,如 Qwen/DeepSeek) · `--runner mock`(免费的测试用例)。防护栏针对每个后端分别强制执行(Claude 的工具黑名单,Codex 的 OS 沙箱);对于 Claude,成本数据是权威的,而对于 Codex 则是 token 预估值。完整详情请见 **[docs/backends.md](docs/backends.md)**。
各阶段 Claude 默认设置(可按次运行覆盖;Codex 在所有阶段使用同一个模型):
```
ingest -> sonnet-4-6 (cheap extraction; never Haiku — misreading scope/RoE costs a lot)
recon -> opus-4-8 (highest-leverage step: the whole audit's quality depends on it)
audit P1..Pn-> sonnet-4-6 (parallel; see note)
validate -> opus-4-8 (cuts false positives)
report -> sonnet-4-6
```
核心概念:验证使用 Opus,它可以消除**误报**,但**无法挽回漏报**——审计模型从未暴露的漏洞已经彻底丢失。因此,对于漏洞检测而言最关键的失败指标(漏报率),审计模型是唯一的控制杠杆。
**模型领域格局(为什么后端是可替换的)。** Argo 刻意将模型隐藏在 `AgentRunner` 接口背后,因为检测质量与模型性能息息相关。技术前沿正在快速发展,并且正专门朝着安全的方向演进:Anthropic 的 **Claude Mythos 5** 被描述为具备所有模型中最强的网络安全能力——强到以至于通用型的 **Fable 5** 都内置了一个分类器,专门将网络安全(以及生化)相关的请求*路由*给 Claude Opus 4.8,而且随后根据美国出口管制指令,对 Mythos/Fable 5 的直接访问受到了限制([Anthropic](https://www.anthropic.com/news/claude-fable-5-mythos-5),[red.anthropic.com](https://red.anthropic.com/2026/mythos-preview/))。这对 Argo 的启示是:随着安全专用模型变得可用,可替换的后端意味着 Argo 只需指向一个更强大的引擎就能变得更强——无需对 pipeline 进行任何更改。目前它可以在上述普遍可用的后端上运行。
校准阶段(前约 5 个项目):将模型覆盖为 `audit -> opus-4-8`。当 prompt 尚未经过验证时,在诊断漏报时,你不希望将“薄弱的 prompt”与“薄弱的模型”混淆。一旦某一类目标能够稳定产出高质量的发现,就可以降级到 Sonnet 以进行规模化扩展。此后按目标设定的规则是:预期高赏金/高严重性 -> 使用 Opus 审计;广泛的低价值扫描 -> 使用 Sonnet。
## 🧪 开发与测试
推荐顺序:先构建 `MockClaudeRunner` + 测试,然后再构建真实的 headless 运行器。这样一来,当你接入真实模型时,粘合逻辑已经过验证,任何剩余的问题都来自于与 Claude Code 的交互,而不是你的逻辑。
Mock 测试用例应该覆盖**失败路径**,而不仅仅是正常路径:一个范围外的发现(范围过滤器)、来自两个不同关注点的相同发现(去重)、一个被反驳的发现(丢弃)、缺失的清单(通配符回退)、在写入过程中中断的会话(部分恢复)、超大的 JSON 结果文件(不假设存在截断)。同时保留一个“录制的真实运行”用例,用来重放真实 Opus 运行的产物,这样可以使 mock 保持逼真,并捕捉输出结构上的偏移。
需要发布的测试:每个阶段边界的 schema 一致性测试,针对 `REPORT.md` 的 golden-file 测试,以及针对去重和验证过滤的回归测试。
## 🌐 活跃目标
你通常在源码上进行工作,但有些项目包含活跃资产。对于这些资产,静态审查只能产生**假设**,而不是可利用的证明。pipeline 绝不会触碰活跃主机:针对每个发现,它会生成一份 `live_verification_plan`(安全、在范围内、非 DoS 的步骤),由你在项目规则范围内针对实例手动进行验证。
## 💡 操作提示
- 将 prompt 纳入 git 版本控制,并记录每次运行使用的版本:你可以对它们进行 A/B 测试,看看哪些能产生被接受的发现。
- SQLite 账本可避免在不同的运行/项目中重复报告相同的漏洞,并追踪你的命中率。
- 记录每次 LLM 调用的成本(在 Max 计划中很有用)。
- 最值得关注的指标是“经验证的发现”与“被分类员接受的发现”之间的比率:如果它们出现背离,请调整验证 prompt。
- 在运行给定的项目之前,务必检查其是否允许使用自动化/AI 工具。
## 📚 更多文档
本 README 是概念性概述。更深度的、面向实现层面的文档位于 [`docs/`](docs/) 目录中:
| 文档 | 内容 |
|---|---|
| [docs/architecture.md](docs/architecture.md) | 模块映射、数据流、`AgentRunner` 抽象、`RunContext`、账本 schema、去重算法 |
| [docs/prompt-synthesis.md](docs/prompt-synthesis.md) | 原型驱动的 prompt 生成器(阶段 2)、特异性自检、从遗留生成器中重用、安全的 meta-prompt 修改 |
| [docs/cli-reference.md](docs/cli-reference.md) | 每个命令和标志,以及示例(`--smoke`、`--budget`、上限、`--calibration` 等) |
| [docs/guardrails.md](docs/guardrails.md) | 不可妥协的防护栏以及**在代码中准确执行它们的位置** |
| [docs/design-decisions.md](docs/design-decisions.md) | **为什么** Argo 直接使用 LLM 且**没有 CPG/AST 引擎**,取而代之使用了什么,我们何时会重新审视这一点,以及针对有效性面临的威胁(论文向) |
| [docs/backends.md](docs/backends.md) | **多后端**:在 Claude Code、Codex CLI (OpenAI) 或本地/开源模型上运行——相关抽象、各后端防护栏映射、成本、跨模型研究 |
| [docs/headless-runner.md](docs/headless-runner.md) | 真实的 Claude Code 集成:使用的标志、JSON 外层结构、上限、错误处理、部分恢复、`--smoke` 运行 |
| [docs/api.md](docs/api.md) | HTTP API(`server/`) — Web UI 的后端:endpoint、运行生命周期、实时状态/SSE、产物白名单 |
| [docs/ui.md](docs/ui.md) | Web UI(`webapp/`) — `python -m argo.cli serve`,无构建步骤的技术栈、视图 |
| [docs/chat-example.md](docs/chat-example.md) | 💬 审问式对话 — 一份真实的实战记录(有根据的解释、误报自我纠正、坦承的漏报) |
| [docs/roadmap.md](docs/roadmap.md) | 计划中的 UI + 高级功能:特性级分析、分阶段构建顺序、待办事项列表(阶段 0 已完成) |
| [docs/configuration.md](docs/configuration.md) | `PipelineConfig` 参考、各阶段模型、预算/上限 |
| [docs/testing.md](docs/testing.md) | 如何运行测试套件、覆盖范围、mock 与 headless 对比 |
## 📄 许可证
Apache License 2.0 — 参见 [LICENSE](LICENSE)。Argo 是**仅用于检测的**工具,旨在用于**已授权的**安全测试(具有安全豁免条款的漏洞赏金项目、你自己的代码、CTF 或研究)。对于你将其指向的任何项目,你有责任确保自身遵守其范围和交战规则。
标签:AI风险缓解, DLL 劫持, DNS 反向解析, 人工智能, 大语言模型, 文档安全, 用户模式Hook绕过, 逆向工具, 静态应用安全测试