codebadger:MCP + CPG 语义代码分析引擎深度解析

项目:https://github.com/lekssays/codebadger
论文:Bridging Code Property Graphs and Language Models for Program Analysis (SVM '26 @ ICSE 2026)
实战成果:5 个真实 CVE,含 Bug Bounty
一、项目概览
| 维度 | 数据 |
|---|---|
| Stars | 77 |
| Forks | 11 |
| License | GPL-3.0 |
| 主要语言 | Python |
| 代码量 | 8,680 行 |
| 测试量 | 7,480 行, 25 个测试文件 |
| 支持语言 | 12 种(C/C++/Java/Python/JS/Go/C#/PHP/Ruby/Swift/Kotlin/Ghidra) |
| 创建时间 | 2025-10-01 |
二、核心架构
┌─────────────────────────────────────────────────────────────┐
│ MCP Client (LLM) │
│ Claude Code / GitHub Copilot / Hermes │
└─────────────────────┬───────────────────────────────────────┘
│ MCP Protocol (HTTP)
↓
┌─────────────────────────────────────────────────────────────┐
│ codebadger MCP Server (FastMCP) │
│ http://localhost:4242/mcp │
├─────────────────────────────────────────────────────────────┤
│ Tools Layer │
│ ├── core_tools (generate_cpg, run_cpgql_query) │
│ ├── code_browsing_tools (list_methods, get_call_graph) │
│ ├── taint_analysis_tools (find_taint_flows, ...) │
│ └── custom_tools (可扩展探测器) │
├─────────────────────────────────────────────────────────────┤
│ Services Layer │
│ ├── JoernServerManager (LRU 池, 端口分配) │
│ ├── CPGGenerator (Joern CLI → CPG.bin) │
│ ├── QueryExecutor (CPGQL → 结构化结果) │
│ ├── CodebaseTracker (状态追踪) │
│ └── GitManager (GitHub URL clone) │
├─────────────────────────────────────────────────────────────┤
│ Storage Layer │
│ ├── SQLite (codebadger.db) │
│ ├── File Cache (playground/cpgs/*.bin) │
│ └── Redis (可选, 会话状态) │
└─────────────────────┬───────────────────────────────────────┘
│ Docker API
↓
┌─────────────────────────────────────────────────────────────┐
│ Joern Container (Docker) │
│ codebadger-joern-server │
│ ├── Joern CLI (CPG 生成) │
│ ├── Joern Server (查询执行, 多实例) │
│ └── Scala CPGQL 引擎 │
└─────────────────────────────────────────────────────────────┘
三、核心组件详解
3.1 JoernServerManager(服务池管理)
关键设计:
- LRU 池:最多 max_active_servers (默认 3) 个活跃 Joern 实例
- 端口分配:动态分配端口,避免冲突
- Watchdog:定期检查服务器健康状态
- 自动驱逐:超出上限时驱逐最久未使用的实例
# LRU 驱动逻辑
def _evict_lru_if_needed(self):
if len(self._ports) < self._max_active:
return None
lru_hash = next(iter(self._lru.items()))[0]
self.terminate_server(lru_hash)
self._lru_eviction_count += 1
3.2 CPGGenerator(CPG 生成引擎)
流程:
GitHub URL / Local Path → Clone → Joern CLI → CPG.bin → Cache
缓存策略:
- 按 source_type:source_path:language:commit_hash 生成 SHA256[:16] 作为缓存键
- CPG 文件存储在 playground/cpgs/{cache_key}/cpg.bin
关键配置:
CPG_GENERATION_TIMEOUT=600 # 10 分钟超时 MAX_REPO_SIZE_MB=500 # 最大仓库大小
3.3 QueryExecutor(查询执行器)
功能:
- 将高层工具调用翻译为 CPGQL 查询
- 执行查询 → 返回结构化 JSON 结果
- 查询缓存 + TTL
配置:
QUERY_TIMEOUT=30 # 查询超时 QUERY_CACHE_ENABLED=true # 启用缓存 QUERY_CACHE_TTL=300 # 缓存 5 分钟
四、工具集详解
4.1 Core Tools(4 个)
| 工具 | 功能 | 使用场景 |
|---|---|---|
| generate_cpg | 生成 CPG | 初始化代码库分析 |
| get_cpg_status | 检查 CPG 状态 | 确认 CPG 是否已生成 |
| run_cpgql_query | 执行原生 CPGQL | 高级用户自定义查询 |
| get_cpgql_syntax_help | CPGQL 语法帮助 | 查询调试 |
4.2 Code Browsing Tools(8 个)
| 工具 | 功能 | 返回内容 |
|---|---|---|
| list_methods | 查找函数 | 函数名、签名、文件位置 |
| list_files | 文件树 | 分页文件列表 |
| get_method_source | 获取函数源码 | 完整函数实现 |
| list_calls | 调用点列表 | caller → callee 映射 |
| get_call_graph | 调用图 | 入向/出向调用关系 |
| list_parameters | 参数列表 | 参数名、类型、顺序 |
| get_codebase_summary | 代码库概览 | 文件数、方法数、调用数 |
| get_code_snippet | 代码片段 | 指定行范围的代码 |
4.3 Semantic Analysis Tools(3 个)
| 工具 | 功能 | 用途 |
|---|---|---|
| get_cfg | 控制流图 | 理解函数内部流程 |
| get_type_definition | 类型定义 | 结构体/类成员 |
| get_macro_expansion | 宏展开检测 | C/C++ 宏分析 |
4.4 Taint & Vulnerability Analysis Tools(14 个)
| 工具 | 功能 | CWE |
|---|---|---|
| find_taint_sources | 定位污点源 | — |
| find_taint_sinks | 定位危险操作点 | — |
| find_taint_flows | source→sink 数据流 | — |
| get_program_slice | 程序切片 | — |
| get_variable_flow | 变量数据依赖 | — |
| find_bounds_checks | 边界检查验证 | — |
| find_use_after_free | 释放后使用检测 | CWE-416 |
| find_double_free | 双重释放检测 | CWE-415 |
| find_null_pointer_deref | 空指针解引用 | CWE-476 |
| find_integer_overflow | 整数溢出 | CWE-190 |
| find_format_string_vulns | 格式字符串漏洞 | CWE-134 |
| find_heap_overflow | 堆溢出 | CWE-122 |
| find_stack_overflow | 栈溢出 | CWE-121 |
| find_toctou | TOCTOU 竞态 | CWE-367 |
| find_uninitialized_reads | 未初始化读取 | CWE-457 |
五、污点分析引擎配置
5.1 Taint Sources(按语言)
C/C++:
["getenv", "fgets", "scanf", "read", "recv", "fread", "gets", "getchar", "fscanf", "recvfrom", "socket", "accept", "fopen", "getline", "realpath", "getaddrinfo"]
Python:
["input", "sys.argv", "os.environ", "request.args", "request.form", "request.json", "request.cookies", "request.headers"]
JavaScript:
["req.body", "req.query", "req.params", "process.env", "fetch"]
5.2 Taint Sinks(按语言)
C/C++:
["system", "popen", "execl", "sprintf", "strcpy", "strcat", "memcpy", "malloc", "free", "printf", "fopen", "write"]
Python:
["eval", "exec", "os.system", "subprocess.Popen", "pickle.load"]
5.3 Sanitizers(清洁器)
C/C++:
["strlcpy", "strlcat", "snprintf", "strtol", "atoi"]
PHP:
["htmlspecialchars", "htmlentities", "mysqli_real_escape_string"]
六、实战成果(TROPHIES)
| CVE | 项目 | 漏洞类型 | 严重性 | 日期 |
|---|---|---|---|---|
| CVE-2026-1801 | libsoup | HTTP Request Smuggling | High | 2026-02-11 |
| CVE-2025-51602 | VLC | Out-of-Bounds Read | Medium | 2026-02-11 |
| CVE-2025-6170 | libxml2 | Stack Buffer Overflow (xmllint) | Medium | 2026-02-02 |
| CVE-2025-6021 | libxml2 | Integer Overflow → Stack Overflow | High | 2026-02-02 |
| CVE-2025-6491 | php-src | Integer Overflow (SoapVar) | High | 2026-02-02 |
关键成果:
- 5 个真实 CVE(含 Bug Bounty)
- libxml2 补丁首次尝试生成正确修复
七、测试覆盖
| 测试文件 | 覆盖内容 |
|---|---|
| test_double_free.py | 双重释放检测 |
| test_format_string.py | 格式字符串漏洞 |
| test_heap_overflow.py | 堆溢出检测 |
| test_integer_overflow.py | 整数溢出检测 |
| test_null_pointer_deref.py | 空指针解引用 |
| test_stack_overflow.py | 栈溢出检测 |
| test_toctou.py | TOCTOU 竞态 |
| test_use_after_free.py | 释放后使用 |
| test_uninitialized_read.py | 未初始化读取 |
| test_program_slice.py | 程序切片算法 |
| test_taint_tools.py | 污点分析工具 |
| test_mcp_tools.py | MCP 协议集成 |
测试密度:src 代码量 : tests 代码量 ≈ 1:0.86(高覆盖)
八、集成方式
8.1 GitHub Copilot
// ~/.config/Code/User/mcp.json
{
"servers": {
"codebadger": {
"url": "http://localhost:4242/mcp",
"type": "http"
}
}
}
8.2 Claude Code
// Claude → Settings → Developer → claude_desktop_config.json
{
"mcpServers": {
"codebadger": {
"url": "http://localhost:4242/mcp",
"type": "http"
}
}
}
8.3 Hermes Agent
通过 native-mcp 技能配置:
# ~/.hermes/config.yaml
mcp_servers:
- name: codebadger
url: http://localhost:4242/mcp
transport: http
九、关键技术亮点
| 亮点 | 说明 |
|---|---|
| 语义导航架构 | LLM 不读全部代码,按需调用工具获取语义信息 |
| LRU 服务池 | 动态管理 Joern 实例,自动驱逐最久未用 |
| 缓存策略 | 按 commit hash 缓存 CPG,代码变更自动失效 |
| 跨语言支持 | 12 种语言的 sources/sinks/sanitizers 配置 |
| 可扩展探测器 | 用户可添加自定义 Scala 查询 + Python 工具 |
| OpenTelemetry | 可选分布式追踪,集成 Jaeger |
| 真实漏洞发现 | 5 个 CVE,含 Bug Bounty |
十、部署流程
# 1. 安装依赖 pip install -r requirements.txt # 2. 启动 Joern Docker docker compose up -d # 3. 启动 MCP Server python main.py & # 4. 验证服务 curl http://localhost:4242/health
十一、与 Hermes Agent 集成建议
| 集成点 | 建议 |
|---|---|
| MCP 配置 | 在 config.yaml 添加 codebadger MCP server |
| 代码审查增强 | 在 github-code-review 技能中调用 find_taint_flows |
| 漏洞扫描流程 | 创建新技能 codebadger-vulnerability-scan |
| 自定义探测器 | 为 Hermes 项目添加 Hermes-specific 漏洞检测 |
十二、总结
三句话总结
- 架构创新:MCP Server + Joern CPG,让 LLM 语义导航大型代码库
- 实战验证:5 个真实 CVE,含首次尝试生成正确补丁
- 可扩展:支持 12 种语言,用户可添加自定义探测器
核心价值
| 价值 | 说明 |
|---|---|
| 解决 Token 困境 | 不加载全部代码,按需获取语义信息 |
| 跨函数漏洞检测 | 污点追踪 + 程序切片,发现跨边界漏洞 |
| MCP 协议兼容 | 可被 Claude Code / Copilot / Hermes 直接调用 |
| 开源 + 可扩展 | GPL-3.0,支持自定义 Scala 查询 + Python 工具 |