| name | trace-sink |
| description | 从 Sink 点反向追踪调用链至 HTTP 入口。读取 sinks.json,对每个 Sink 使用 JetBrains 引用查找递归追踪调用者,分析参数传递和过滤情况,判断参数可控性。用于:漏洞调用链追踪、反向污点分析。触发词:trace sink、反向追踪、调用链分析、sink 追踪、Phase 4。 |
Sink 反向追踪 (Phase 4)
适用场景
- 对
find-sink 发现的 Sink 点进行反向调用链追踪
- 判断 Sink 参数是否可被外部输入控制
- 作为
java-audit Phase 4 被调度执行
不适用场景
- 还没有 Sink 清单 → 先执行
find-sink
- 需要从路由入口正向追踪 → 使用
trace-preauth
前置条件
- Serena MCP 已连接,目标项目已激活
.audit/sinks.json 已存在(由 find-sink 生成)
反幻觉铁律
1. 调用链每一跳必须通过 jet_brains_find_referencing_symbols 或 jet_brains_find_symbol 实际确认
2. 每一跳必须标注 文件路径:行号
3. 参数传递关系必须从代码中读取确认,不得推测
4. 无法确认的链路标记为 [Hypothesis]
工作流程
Step 1: 读取 Sink 清单
读取 .audit/sinks.json,获取所有 Sink 点列表。按 confidence 从 high 到 low 排序处理。
Step 2: 逐个 Sink 反向追踪
对每个 Sink 执行:
-
获取 Sink 方法详情
- 调用
jet_brains_find_symbol(method_name, include_body=true) 获取完整代码
- 确认 Sink 调用确实存在
- 标注 Sink 参数在方法签名中的位置
-
查找调用者(第 1 跳)
- 调用
jet_brains_find_referencing_symbols(symbol=method_name) 找到所有调用位置
- 对每个调用者,用
jet_brains_find_symbol(include_body=true) 读取方法体
- 分析:Sink 参数在调用处来自调用者的参数 / 局部变量 / 硬编码值
-
递归追踪(第 2–5 跳)
- 对参数来自调用者参数的情况,继续向上追踪
- 调用
jet_brains_find_referencing_symbols 查找上层调用者
- 终止条件:
- 到达 Controller/Servlet 入口层(参数来自 HTTP 请求)→ HTTP 可达
- 到达最大深度 5 层 → 追踪截断
- 参数来自硬编码/常量 → 不可控,停止
- 参数经过安全过滤 → 记录过滤方式
- 无更多调用者 → 入口不明
-
参数流分析
在每一跳中检查:
- 参数是否直接传递(未修改)
- 是否经过类型转换 / 编码 / 解码
- 是否经过白名单 / 正则 / 长度校验
- 是否经过 sanitize 函数
-
与鉴权状态交叉
- 如果调用链到达的入口在
.audit/preauth-routes.json 中 → 标记 preauth 可达
- 否则标记 postauth 可达 或 非 HTTP 入口
Step 3: 输出报告
输出 .audit/trace-sink.md:
# Sink 反向追踪报告
## SINK-001: SQL注入 - UserDao.findByName
**Sink**: `UserDao.findByName()` at `UserDao.java:42`
**Sink 代码**: `String sql = "SELECT * FROM user WHERE name = " + name;`
**漏洞类型**: SQL 注入
**调用链**:
1. [HTTP Entry] `UserController.search()` at `UserController.java:28`
- 参数来源: `request.getParameter("name")` → `name`
↓
2. `UserService.searchUser(name)` at `UserService.java:55`
- 参数传递: `name` → `name` (直接传递,未过滤)
↓
3. [SINK] `UserDao.findByName(name)` at `UserDao.java:42`
- SQL拼接: `"SELECT * FROM user WHERE name = " + name`
**参数可控性**: 完全可控
**防护措施**: 无
**鉴权状态**: postauth (需要登录)
**状态**: [Confirmed] / [Hypothesis]
---
注意事项
- 追踪深度限制 5 层,超过时截断并标注
- 同一 Sink 有多条到达路径时全部记录
- 接口方法需查找实现类的具体实现
- 注意同名方法的不同重载版本