关于 Lachesis
Lachesis 使用基于编译器的代码属性图分析 C、Python 和 TypeScript/JavaScript。开发者和编码 Agent 可通过命令行、Python 库或 MCP 服务导航调用与数据流、调查污点路径并查看潜在安全线索。
主要功能
- 01为三种语言构建编译器级图谱
- 02跨语言符号与调用导航
- 03数据流与污点分析
- 04附带证据的安全线索
- 05支持命令行、Python 库和 MCP
适用场景
- 01追踪代码库中的调用方与被调用方
- 02检查外部输入是否到达敏感操作
- 03调查 C 中的重复释放和释放后使用路径
MCP 相关
MCP 服务允许 Agent 构建或打开代码图谱,并使用工具进行搜索、导航、数据流和污点分析及证据查看。通过 `lachesis mcp` 启动。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Lachesis
Lachesis 会读取你的代码并构建一张代码地图。然后,你可以向这张地图提问,例如:哪个函数调用了这个函数,这个值会流向哪里,以及恶意输入能否到达危险位置。
它支持 C、Python 和 TypeScript/JavaScript,并将它们整合到同一张地图中。
这是什么?
像 grep 这样的搜索工具会告诉你代码中某个词出现的位置。Lachesis 则不同,它会追踪实际的数据。它能告诉你某个值的来源、接下来的流向,以及外部请求能否到达危险位置,例如在没有登录检查的情况下调用数据库。
为此,它会像编译器一样读取代码,而不是通过文本模式猜测。因此,即使名称被重命名或以特殊方式导入,它也不会漏掉调用。
你可以通过三种方式使用它:作为终端命令、Python 库,或供 AI Agent 使用的 MCP 服务。
快速开始
安装后,指定一个文件夹:
python -m pip install lachesis-cpg
lachesis ./my-project
它会构建并保存地图,然后打印出线索。线索是指外部输入能够在没有任何检查的情况下到达敏感位置的地方。每条线索都是一个需要进一步调查的问题,而不是最终结论。
✓ compiling (0.7s)
2,677 nodes, 4,539 edges from typescript-compiler-api
✓ finding entrypoints that reach sensitive effects (0.1s)
2 leads (lens=all)
1. [0.810] handleWebhook (http/webhook.ts:10, route) -> findById(documentId) [database]
a caller that passes no recognized guard can read or write data
through findById(documentId) starting from handleWebhook
2. [0.810] handleWebhook (http/webhook.ts:10, route) -> findById(invoiceId) [database]
this function branches on something, but no login-style check is seen here
你也可以提供 git URL,而不是文件夹:
lachesis https://github.com/owner/repo。它会将代码下载到临时文件夹中,扫描后再清理。
首次扫描项目会比较慢。之后,地图会缓存在 ~/.lachesis/cache 下,因此后续每次运行都会很快。
三种使用方式
终端。 使用一个 lachesis 命令即可。lachesis ./repo 是最简单的入口。
如果需要更多控制,可以将步骤分为三个阶段:
lachesis build ./my-project graph.kuzu # step 1: read the code, build the map
lachesis enrich graph.kuzu # step 2: work out the data flow
lachesis analyze graph.kuzu --summary # step 3: print the leads
lachesis explain graph.kuzu tree.c:1487 # show all the evidence for one spot
Python 库。 打开一次地图,然后随心所欲地提出问题。
import lachesis
a = lachesis.Analysis.build("./my-project", "graph.kuzu", enrich=True)
leads = a.scan()
print(leads.summary())
print(a.explain_sink("tree.c", 1487)) # all the evidence for one spot
可运行的示例脚本位于 examples/。
MCP(适用于 AI Agent)。 启动服务后,Agent 就可以自行构建并查询地图:
lachesis mcp ./my-project
关于在 Cursor、VS Code、Claude 和 Docker 中进行设置,请参阅下文的 MCP。
你可以询问什么
构建好映射后,就可以使用以下操作。你可以在终端中、通过 Python 库,或将其作为 Agent 使用的 MCP 工具来调用:
| 你想了解什么 | 工具 |
|---|---|
| 这部分代码是围绕什么构建的? | hubs |
| 这个名称在哪里? | search |
| 谁调用了它?它又调用了什么? | callers、callees |
| 显示实际源代码 | read_body |
| 这个文件或文件夹里有什么? | open_file、open_folder |
| 这个值会流向哪里?什么会传入这个位置? | flow、sources_of |
| 这个输入会到达那个位置吗? | reaches(提供路径,或明确说明不会到达) |
| 这个指针指向什么? | points_to、aliases |
| 外部输入会在哪里到达危险位置? | taint |
| 这个 C 对象是否被释放了两次,或在释放后仍被使用? | C 生命周期分析 |
| 哪些入口点在没有检查的情况下到达敏感位置? | scan(线索) |
| 一次调用即可获取某个位置的所有证据 | explain |
每个回答都会附带置信度。有些链接是精确的,有些是可靠的推测;Lachesis 会明确指出何时是在推测,而不会将其隐藏。请将回答视为证据,而非定论。
MCP
在构建映射的位置运行 lachesis mcp。你可以传入 graph.kuzu 路径,但不是必须的。不带参数启动时,当你指定一个代码仓库后,Agent 会自行构建映射。
一键安装(使用 uvx,无需安装步骤):
也可以手动配置。如果软件包已安装:
{
"mcpServers": {
"lachesis": { "command": "lachesis", "args": ["mcp"] }
}
}
也可以让 uvx 在首次运行时获取软件包,无需安装:
{
"mcpServers": {
"lachesis": { "command": "uvx", "args": ["--from", "lachesis-cpg", "lachesis", "mcp"] }
}
}
也可以在 Docker 中运行,镜像中已包含全部三种语言:
{
"mcpServers": {
"lachesis": {
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "/path/to/your/project:/src",
"ghcr.io/unboundcompute/lachesis:edge"]
}
}
}
更多客户端说明请参见 docs/queries.md。
语言
每种语言都由真正的编译器或其自身的解析器读取,绝不会靠文本猜测。
| 语言 | 使用什么读取 | 文件类型 |
|---|---|---|
| TypeScript / JavaScript | TypeScript 编译器 | .ts .tsx .mts .cts .js .jsx |
| Python | Python 自带的 ast + symtable | .py .pyi |
| C | Clang | .c .h |
混合项目只有一张映射,而非三张。Python 函数和它调用的 TypeScript 函数位于同一张映射中,同样的工具也适用于两种语言。
有两点限制值得了解。Python 没有类型检查器,因此会按名称匹配属性调用。C 一次读取一个文件,因此不会跟踪它看不到的函数指针表中的调用。每种语言都会说明自身的能力与限制。
工作原理
Lachesis 分三步工作,每一步都是一条命令。
- build:使用真正的编译器读取代码,生成一份由符号和调用组成的纯映射。这一步速度很快,而且大多数代码导航只需要这一步。
- enrich:推断数据如何流经映射。这一步不会在构建时执行。只有问题所需的部分流程才会被计算,随后缓存起来。
- analyze:遍历映射并输出线索。这些线索是敏感位置,会根据已知的漏洞模式进行评分和匹配。分析有时间限制,因此大型项目不会卡住。
此外,还有一个 C 生命周期扫描。有些漏洞(例如重复释放同一个对象,或在对象释放后继续使用)不只涉及某个位置,而是涉及对象的整个生命周期。单独的扫描会跟踪每个 C 对象的分配、释放和使用,并报告重复释放和释放后使用,同时提供展示问题发生过程的路径。
映射会保存为一个文件夹(graph.kuzu)。其中包含一个嵌入式数据库和一个小型索引文件。这个文件夹本身就是映射。所有工具都会直接读取它。
更多详情请参阅 docs/graph-model.md(映射中的内容)和 docs/scaling.md(大型代码库、内存和速度)。
安装
python -m pip install lachesis-cpg
支持 Python 3.10–3.12。分析 Python 代码无需额外安装。扫描 TypeScript/JavaScript 需要将 node 加入 PATH,扫描 C 需要 clang。如果缺少其中任何一项,程序会给出清晰的提示,而不是崩溃。
从克隆的仓库开始操作(适用于贡献者):
git clone https://github.com/UnboundCompute/lachesis && cd lachesis
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
npm ci
cargo build --release --manifest-path native/clang_frontend/Cargo.toml
后续阅读
examples/:五分钟快速入门,以及每项功能对应的可运行脚本。docs/graph-model.md:映射中的内容。docs/queries.md:所有提问方式。docs/scaling.md:大型代码库、内存和 CI。
路线图
近期完成:
- **C 生命周期漏洞。**查找 C 对象的重复释放和释放后使用,并提供展示问题发生过程的路径;对于没有问题的路径不会误报。
- **大型代码库。**大型多语言代码树会分成多个部分并行构建,再合并为一张映射,同时不超出设定的内存预算。
- **直接扫描 git URL。**将
https://…交给它,它就会下载、扫描并清理。 - **一个工具,三种入口。**终端命令、Python 库和 MCP 工具由同一套代码驱动。
接下来:
- 跨函数的 C 生命周期漏洞:在一个函数中释放,在另一个函数中使用。
- 一个“此输入能否到达此位置?”的问题:跨文件和语言返回一条路径,或明确表示无法到达。
状态
Lachesis 仍处于早期阶段,迭代很快。目前映射、存储、导航和 MCP 工具,以及 C 生命周期扫描均可正常工作,并通过了测试套件的检查。目前生命周期扫描仅支持 C,且只能在单个函数内工作。已记录一个已知误报。1.0 之前工具仍可能发生变化;CHANGELOG 列出了相关变更。
许可证
AGPL-3.0。请参阅 LICENSE。你可以使用、研究、修改和分享本项目,包括用于商业用途。如果你将修改后的版本作为网络服务运行,则必须向用户分享修改后的源代码。如果这不适合你的情况,也可以考虑单独的商业许可证。请参阅 CONTRIBUTING.md 或提交 issue。
安全
发现安全漏洞?请不要公开提交 issue。如何私下报告,请参阅 SECURITY.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。