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 层面。 ![端到端 pipeline 流程](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/01bce4a4f2214517.svg) ## 🪪 两种模式:通用审计与漏洞赏金 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。 ![Prompt 增强:从通用到自定义](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/cb773f662e214522.svg) 这种划分是**原型驱动的**:阶段 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绕过, 逆向工具, 静态应用安全测试