krishkuchroo/orion
GitHub: krishkuchroo/orion
一款基于 GraphRAG 和 Claude 多智能体的代码安全扫描器,通过构建代码图并隔离验证流程来发现和确认漏洞,兼顾高召回率与低误报。
Stars: 0 | Forks: 0
# Orion
一个独立的 GraphRAG 代码安全扫描器。将其指向一个代码库:Orion 会基于 [Joern](https://joern.io) CPG 构建代码图,一队 Claude agent 通过对该图进行推理来发现安全问题(每一个论断都通过只读 Cypher 查询来提供依据,而不是凭记忆断言),并且在报告之前,会有一个单独的验证 agent 独立确认每一条线索。
其目标在于针对固定的规则目录无法覆盖的任意代码库实现高召回率,同时避免误报泛滥。在 OWASP NodeGoat 基准测试中,Orion 以零误报发现了 15 个漏洞中的 14 个,而确定性目录扫描器则一无所获。(第 15 个漏洞,即“包含已知漏洞的组件”,需要当前图谱中不具备的 CVE 数据源。)
## 使其值得信赖的那条规则
发现和验证是不同的工作,由不同的 `claude -p` 会话运行。发现团队提出候选线索。一个单独的验证器(它从不会看到发现的对话记录)会根据真实的源码(通过 `fp-check` 技能)和图重新推导每一条线索,然后返回 `CONFIRM`(确认)、`REJECT`(拒绝)、`INCONCLUSIVE`( inconclusive,结论不明)或 `ERROR`(错误)。一个验证自己猜测的 agent 等于是在给自己的作业打分;会话隔离使得在每次扫描都没有人工介入的情况下,其输出依然具有说服力。崩溃的验证器调用会变为 `ERROR`,绝不会静默返回 `CONFIRM`。
## 工作原理
三个层级:
1. **构建。** `graph_build.build(repo)` 在代码库上运行 Joern(如果存在预构建的 `cpg.bin` 则直接复用,否则在源码上运行 `joern-parse`),并将 CPG 标准化为 Neo4j 中包含 8 个节点、5 条边的规范 schema:`CpgFile`、`CpgMethod`、`CpgCall`、`CpgModule`、`CpgParameter`、`CpgReturn`、`EntryPoint`、`Dependency`,以及 `CONTAINS_CALL`、`RESOLVES_TO`、`DEFINED_IN`、`FLOWS_TO` 和 `ENTERS_AT` 边。每个节点和边都带有 `scan_id` 以实现扫描隔离。
2. **编排。** `discover.discover` 并行展开四种发现“形态”(A 数据流,B 缺失控制,C 禁用或回退的修复,D 模式与依赖)。每种形态都是一个单独的 `claude -p` 会话,调用只读的 MCP 工具 `run_cypher`、`semantic_search` 和 `get_schema`。线索会先进行去重,然后 `verify.verify_all` 会在各自全新的会话中验证每一条线索。
3. **框架。** `cli.py` 通过实时的、可停止的进度监视器将其端到端连接起来。`report.py` 呈现带有证据引用的排名报告,而 `scripts/run_nodegoat_eval.py` 负责对召回率进行评分。
### 构建上与框架无关
Orion 不内置任何框架目录。语言和框架知识集中在一个地方,即 `graph/profiles.py`:
- 一个 profile 回答了三个问题:什么算作攻击者可控的 source,entry point 是什么样子的,以及发现 prompt 所使用的词汇表。
- `EXPRESS` 形式化了 JavaScript/Express 的请求对象模型(`req.*`)。
- `GENERIC` 是针对任何未知技术栈的后备方案。Entry point 是通过结构化方式检测到的(接受参数的第一方调用图根节点和回调处理程序),而这些参数就是污点 source,因此不需要任何请求对象命名约定。当代码库明显属于某一个时,`select_profile()` 会选择 EXPRESS,否则选择 GENERIC。
语言检测是基于标记的(`graph/joern_adapter.py`):`package.json` 映射到 JavaScript 前端,`go.mod` 映射到 Go,`pom.xml` 映射到 Java,以及 `requirements.txt` / `setup.py` / `pyproject.toml` 映射到 Python。包含多个标记的代码库会被明确标记出来,而不是被默默猜测;如有需要,可以使用 `orion scan --language ` 来覆盖检测结果。依赖关系会从相同的清单中解析为 `Dependency` 节点(`graph/deps.py`),并且发现的 prompt 会锚定在填充好的 `:EntryPoint` 和 `:Dependency` 节点上,因此即使是未知框架的代码库也能正常工作,而无需任何人为它编写 profile。
除了 NodeGoat (Express) 之外,Orion 还针对 PyGoat(一个它从未见过的、故意设置了漏洞的 Django 和 Flask 应用)进行了运行。GENERIC profile 在同一个代码库的这两个框架中确认了 20 个发现,包括远程代码执行、不安全的反序列化、服务端请求伪造、服务端模板注入以及六个已知存在漏洞的依赖项,而且完全不需要进行特定于框架的调优。
## 设置
前置条件:
- **Neo4j。** Orion 通过 `docker-compose.yml` 运行自己的 Neo4j 社区版实例(主机端口 7688 用于 Bolt,7475 用于 HTTP)。必须确保 Docker Desktop 正在运行。
- 位于 `~/joern/joern-cli` 的 **Joern** CLI(包含 `joern-parse`、`joern-export`)。如果它位于其他位置,请设置 `JOERN_HOME`。
- **`claude` CLI** 版本 2.1.210 或更高,位于 `PATH` 中,以无头模式运行(支持 `--mcp-config`、`--json-schema`、`--add-dir`)。
- **Python** 3.11 或更高版本,并带有虚拟环境。
```
docker compose up -d # Neo4j on 7688 and 7475
python -m venv .venv && ./.venv/bin/pip install -e ".[semantic,dev]"
cp .env.example .env # optional: defaults already work
```
测试夹具(NodeGoat 示例应用及其预构建的 CPG)未被提交;请在 `fixtures/NodeGoat/` 下放置一个带有预构建 `cpg.bin` 的代码库,以便在本地运行构建和评估测试。
## 运行
```
orion scan ./path/to/repo # build, discover, verify, report
orion scan ./repo --watch # follow live progress (stoppable with Ctrl-C)
orion scan ./repo --json findings.json # also write verdicts as JSON
orion scan ./repo --language golang # override language detection
orion scan --scan-id # re-run against an already-built scan graph
orion scan ./repo --quiet # suppress per-event prints (still logs to file)
```
每次运行都会将其进度事件记录到 `.orion/runs///progress.jsonl` 中。
### NodeGoat 评估
```
./.venv/bin/python scripts/run_nodegoat_eval.py # build and score fixtures/NodeGoat
./.venv/bin/python scripts/run_nodegoat_eval.py --scan-id # score an existing scan
```
这将打印出一个与 `tests/ground_truth_nodegoat.py` 匹配的 N-of-15 召回率表,以及任何与 ground-truth 项不匹配的确认发现(误报候选)。
## 布局
```
orion/
contracts.py frozen data contracts (Lead, Verdict, ProgressEvent): the integration spine
config.py environment config (Neo4j 7688, model, timeouts, MCP config path)
graphdb.py read-only Neo4j access (write Cypher is rejected)
graph/
joern_adapter.py Joern CPG to canonical schema (B2/B3 fixes; entry-point and language detection)
profiles.py language and framework profiles: the one place framework knowledge lives
deps.py manifest to Dependency nodes (package.json, requirements, pom, go.mod)
schema.py canonical node and edge identity plus the batched writer
persist.py atomic clear-and-load into Neo4j
graph_build.py build orchestration to scan_id
mcp_server.py FastMCP server exposing run_cypher, semantic_search, get_schema (all read-only)
claude_cli.py headless claude -p driver (MCP, retries with backoff, diagnostics salvage)
strategies.py the four discovery shape prompts (framework-agnostic, profile-parameterized)
discover.py async four-shape discovery fleet to candidate leads
verify.py independent per-lead verifier (fp-check) to a verdict per lead
embed.py semantic index (jina code embeddings into a Neo4j native vector index)
report.py ranked, evidence-cited output
monitor.py live progress log plus the --watch tail
cli.py orion scan
scripts/run_nodegoat_eval.py full-pipeline recall harness against the 15-vuln ground truth
```
## 测试
```
./.venv/bin/python -m pytest -m "not slow" # fast suite (no Claude tokens); needs Neo4j up
./.venv/bin/python -m pytest -m slow # live tests that spend real Claude tokens
```
快速测试套件涵盖了构建器、只读图保护、MCP 工具、profile 和语言选择、报告排名以及进度监视器。当无法连接到 Neo4j 时,它会干净地跳过。
标签:Neo4j, 代码安全审计, 代码属性图, 图检索增强生成, 大模型AI智能体, 请求拦截, 逆向工具, 错误基检测, 静态代码分析