一键导入
dataflow-analysis
跨函数白盒数据流追踪——基于 SyntaxFlow / yak MCP 的 SSA 引擎,对已知 source / sink 证明跨函数 source→sink 静态可达性,产出链路证据。source-sink 集合按调用者意图动态决定,不绑定具体漏洞 类型。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
跨函数白盒数据流追踪——基于 SyntaxFlow / yak MCP 的 SSA 引擎,对已知 source / sink 证明跨函数 source→sink 静态可达性,产出链路证据。source-sink 集合按调用者意图动态决定,不绑定具体漏洞 类型。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
白盒建模——一次深度建模产出五张共享模型:项目架构(技术栈/分层/框架自有封装/闭源依赖位置)、 入口点(路由/中间件信任边界)、认证与权限(会话/角色/多租户/归属字段)、业务(实体/流程状态机/ 业务不变量/高价值资产)、全局威胁(攻击面×漏洞类别的适用性映射,供下游逐一全测)。本能力不做漏洞判定,为后续 漏洞维度分析建立共享底图。
OS 命令注入综合检测——覆盖直接命令拼接 / shell 元字符 / 参数注入 / 间接 RCE,按回显 / 时间 / 带外通道分诊。 流量中参数值含主机名 / URL / 文件名 / 命令片段、响应里出现 shell 错误关键字(`/bin/sh` / `cmd.exe` / `command not found`)、注入 `sleep N` 耗时增加、上传后异步处理链路时使用。
文件上传多策略综合检测——覆盖扩展名 / MIME / 魔术数 / 解析漏洞 / 上传链组合(LFI / Zip Slip / SVG XSS / SVG XXE)。 流量含 multipart/form-data 上传、响应回显落盘路径、上传后文件可被 GET 解析、上传字段含 filename / path 可控时使用。
IDOR 水平越权检测 — 通过替换资源标识符(ID/UUID/路径)访问他人资源的风险;适用于用户资料、订单、文档、租户隔离场景。
检测路径穿越和本地文件包含(LFI)风险;当目标存在文件读取/下载/预览功能且含路径参数时触发;适用于文件下载、日志查看、模板加载等场景。
黑盒建模 — 迭代式攻击面建模,按站点级 / 页面级 / 功能级三粒度推进;进入新页面即触发一次页面级建模、切换新身份各刷新一次,产出端点账本与页面语义模型,为后续漏洞维度的适用性判断提供依据。
| name | dataflow-analysis |
| description | 跨函数白盒数据流追踪——基于 SyntaxFlow / yak MCP 的 SSA 引擎,对已知 source / sink 证明跨函数 source→sink 静态可达性,产出链路证据。source-sink 集合按调用者意图动态决定,不绑定具体漏洞 类型。 |
| when-to-use | 当需要对 SAST 候选集做数据流确认、验证污点传播可达性,或需要分析 request→session、cookie→auth、owner→mapper 等跨函数调用链路时 |
| allowed-tools | bash,read_file,list_files,rg |
| mcp | ["syntaxflow","yak"] |
| user-invocable | true |
| argument-hint | [target_path] [--lang java|go|python|js|php|c] |
| arguments | ["target_path","lang"] |
本能力是 Cat-B-Cross 跨漏洞数据流工具,按"已定位 source/sink + 链路不可见性 + 跨端点共源"识别命中场景。起点既可来自直接阅读 / 框架侦察自定位的 sink,也可来自上游 sast-scan 候选——后者只是可选加速输入,其缺位 / 空命中不阻塞本能力(参 §5 起点来源)。
直接定位 sink 维度(主路径):
承接 sast-scan 候选维度(可选加速):
needs_dataflow_confirmation 桶条目——sink pattern 已命中但跨函数 source 可达性未证,可直接消费其 file_location 省去再定位Runtime.exec(String[]) / JdbcTemplate.queryForObject(sql, args) 等"同名 API 既能拼也能参数化"的弱 sink,需追上游确认实际形态已定位 source/sink 但中间链路问题维度:
BaseRepository / CommonMapper / CmdUtil.run 等)把标准 sink 藏在 wrapper 内交叉端点维度:
pattern_id 的端点集合需统一证明可达性(避免逐 handler 重复手工追)反向信号(不命中本能力):
本能力 n/a(原因:跨多漏洞类型,单类漏洞成因归对应单漏洞 skill 的 §2。SQLi 成因看 code-audit/sast-scan 协作的 SQL 注入审计能力;命令注入成因看对应能力;反序列化成因看对应能力。本能力只提供「跨函数链路证明」工具,不承担成因解释)。
本能力作为跨漏洞数据流工具,source-sink 集合按调用者意图动态决定(由直接阅读 / 框架侦察自定位、用户给定、或 sast-scan 候选等 source / sink 模式驱动);本节只描述通用框架与 SyntaxFlow 表达方式,不固化某类漏洞的 source-sink 列表——单漏洞专属集合归对应单漏洞 skill 的 §3。
Runtime.exec / eval / exec / os.system / template engine evaluate${} / 字段名 / 排序方向位置new File / Path.resolve / 上传写盘 / 模板加载ObjectInputStream.readObject / pickle.loads / Jackson polymorphicHttpClient.execute / requests.get / SSRF 出站调用innerHTML / 直接写 response body(XSS sink)*Mapper / *DAO / *Service)建立调用图@Service / Django middleware / Express middleware / AOP 拦截层是否引入过滤SyntaxFlow DSL 是 SSA 上的图查询语言。基本运算符:
#>(一跳直接定义) / #->(递归到定义链起点)->(一跳直接使用) / -->(递归到使用链终点)$x #{depth: 5}-> $y; / $x -{depth: 3}-> $y;(首次调试建议加,避免大项目 SSA 图爆炸)Method.parameter() as $sink;(先选具体调用 / 方法链作 anchor,再用 * as $arg 捕获关心的参数)alert $var for { message: "...", level: info };(每条规则至少一个 alert,否则视为无可见输出)完整 DSL 语法 / Cookbook / 各类 sink 查询模板见 references/syntaxflow-cookbook.md。
本能力 n/a(原因:跨多漏洞类型,攻击变体属漏洞自身属性,归对应单漏洞 skill 的 §4。本能力只对"任意 source → 任意 sink 链路"做静态可达性证明,不分变体)。
本能力的"入口点"是「已知 source / sink 端点 + 中间链路问题」——不像单漏洞 skill 从项目结构盘点 sink,本能力直接从上游候选或用户给定端点起步。
起点来源并列,按上下文选,无固定优先级;sast-scan 候选只是可选加速输入,缺位时直接走自定位(grep / read / 框架侦察),不阻塞:
rg 盘点危险 sink(含项目自有 wrapper),按代码 pattern 锚定,再跨函数追 source。这是不依赖任何上游产物的主路径shared/coverage-ledger/findings/sast-scan.jsonl 里 confidence=needs_dataflow_confirmation 的条目,可直接读其 file_location 当 sink 位置省去再定位;source 由本能力跨函数追溯。无此产物或其空命中时不影响上述自定位路径下列项目类型仅作示例,以目标实际栈为准。
yak MCP 加载目标项目,ssa_compile(target, language, program_name) 编译到 SSA IRprogram_name 用项目稳定名(如 petclinic-main),便于复用查询追踪方向有两个维度,按上下文选:
#->)追上游定义链。why:sink pattern 更具体、anchor 收敛性强,比从 source 正向追的 SSA 图爆炸面小-->)追下游使用链。why:交叉端点场景下用一次正向追覆盖多个 sink 比逐 sink 反向追高效直接写 SyntaxFlow 容易漏对项目实际 IR 形态,why:项目自定义 wrapper / 注解处理器 / Lombok 生成代码会让 IR 与源码长得不一样。用 ssa_query 先探索:
<ANCHOR>(* as $arg) as $call; alert $call,看实际匹配到的调用点是否符合预期本能力跨语言可用,不同语言项目的 SyntaxFlow 查询差异主要在 source / sink anchor 表达式以及 IR 形态——业务调用语义相同,但 anchor 写法不同。
下列框架 / 语言示例仅作类似项目示例,不限于此;以目标实际栈为准。
| 语言 / 框架 | source anchor 形态 | sink anchor 形态 | 项目 IR 差异要点 |
|---|---|---|---|
| Java / Spring | @RequestParam / request.getParameter / @RequestBody 注解参数 / request.getAttribute | Runtime.getRuntime().exec / JdbcTemplate.queryForObject / EntityManager.createNativeQuery | Bean 注入 / AOP 拦截 / Lombok 生成 getter — anchor 要覆盖代理类与原始类两套方法名 |
| Java / MyBatis | 同上 + service 方法参数 | Mapper 接口方法 + @Select / XML 模板 ${} | XML 不在 SSA IR 内 — 需 grep XML + SSA 联合,参 cookbook 模板 F |
| Go | gin.Context.Query / Context.PostForm / Context.GetHeader / struct binding | db.Raw / db.Exec(fmt.Sprintf(...)) / os/exec.Command / Runtime | 接口实现 / 方法集 — anchor 写接口方法时要兼容所有实现;channel 传值跨 goroutine 在 SSA 上是边断点 |
| Python / Django | request.GET.get / request.POST / request.META / form cleaned_data | cursor.execute / Model.objects.raw / os.system / subprocess.Popen | 动态属性访问(getattr / **kwargs)— SyntaxFlow 静态追踪到此为边断点(参 §11) |
| JS / Node.js / Express | req.query.x / req.body.x / req.cookies / req.params | sequelize.query / child_process.exec / template literal 拼接 | CommonJS vs ESM 导入;解构赋值(const {x} = req.body)— anchor 要兼顾解构 alias |
| PHP / Laravel | $request->input / $_GET / Request::input | DB::raw / whereRaw / eval / system | Facade 静态代理(DB:: → \Illuminate\Support\Facades\DB)— anchor 写实际实现类 |
跨语言通用要点:
CmdUtil.run / BaseRepository.rawQuery)—— 漏掉就误以为"项目无 sink"加载本 skill 时按这些问题思考(按 sink 语义、不按业务命名):
Runtime.exec 封装成 CmdUtil.run 会让命中数异常少static-unknown?默认 not_vulnerable 是白盒最常见的诚信底线失守(参 §11)本能力只到链路证明——动态利用证据由黑盒 / graybox 流程取证;单漏洞 confirmed 结论由对应单漏洞 skill 给出,本能力只提供"静态可达"素材。
跨函数数据流追踪的核心动作:锚定(Anchor) → 捕获(Capture) → 追踪(Trace) → 输出(Alert)——这不是固定步骤编号,而是写每条 SyntaxFlow 规则的四个递进维度。完整 DSL 语法、各类 sink 查询模板、Alert 规范、限深策略见 references/syntaxflow-cookbook.md。
前置:SSA 编译 + IR 探索
ssa_compile(target, language, program_name)——若失败 / 语言不支持 → 走 cookbook 的 fallback 协议锚定(Anchor):选具体调用点 / 方法链作起点(如 Runtime.getRuntime().exec / Files.write / .parse / .evaluate)
*.* #-> ... 全局 wildcard)召回大量噪声 SSA 图爆炸;太窄会漏掉项目自有 wrapper。why:先按已知标准 API 锚定,命中后看是否需要把 wrapper API 加入 anchor 集合捕获(Capture):用 * as $arg 把关心的参数 / 值抓出来
JdbcTemplate.queryForObject(sql, args)——sql 是 sink 上下文、args 是参数化绑定通道,追错参数等于追错语义)追踪(Trace):默认 #->(必要时先 #> 粗定位);首次调试加 depth: 3~8 限深
输出(Alert):每条规则至少一个 alert $var for { message: "...", level: info }
示例 1:从 SQL sink 反向追到 HTTP source
锚定 JdbcTemplate.queryForObject 第一个参数为 sink,TopDef 递归到 source;若 source 命中 @RequestParam 注解或 request.getParameter 调用 → 静态可达;若链路中出现 WhitelistUtil.check / Integer.parseInt 等过滤调用 → 标 static-unknown,需人工判定过滤是否完整。
示例 2:交叉端点 source 一次正向追
source 是 filter 派生的 request.setAttribute("userId", decoded);锚定 setAttribute("userId", ...),BottomUse 一次追到所有读取 getAttribute("userId") 的 handler,再对每个 handler 看其下游 sink。
示例 3:二阶链路追
source 是 INSERT 写入字段(INSERT INTO user(email) VALUES(?));BottomUse 追该字段被哪些 SELECT 引用,每个回读点单独追是否参数化。
needs_dataflow_confirmation 桶 → 本能力按 file_location 锚定 sink,反向追 source 可达性(source, sink) 对在多端点出现 → 每个 entry_point 单独成行(参 §9)confidence 从 needs_dataflow_confirmation 升为 dataflow-confirmed(即本能力的 static-confirmed),写入 shared/coverage-ledger/findings/dataflow-analysis.jsonldataflow-confirmed 条目 + 黑盒可观测效果证据 → 最终判 confirmed以下是已知的检查角度,作为基线起点而非必检硬清单。结合目标代码动态调整,按三态标注(
[x]/[-]/[+])处置。
static-unknown,未默认 not_vulnerable(source, sink, entry_point) 三元组独立成行落 jsonl闭环判定 / 取证完整性 / 破坏性动作以 common/closure-verification.md 为准,下面只列本能力特有的判定上限与产物契约。
为什么这里是「必须」:本节属交付契约——本能力的产物结构是下游单漏洞 skill /
result-with-file机器消费的接口;产物聚合或省略会让单漏洞 skill 无法回溯具体 file:line 与跨函数链路,整条链路失效,因此是刚性要求。
本能力作为跨漏洞数据流工具,判定上限为 static-confirmed(source-sink 链路静态可达,跨函数链路完整无 unknown 断点),不等于动态 confirmed,且不独立给出单漏洞 confirmed 结论——本能力提供"链路证明"作为单漏洞 skill 升级 confirmed 的素材。
| 链路状态 | 上限状态 | 升级路径 |
|---|---|---|
| 跨函数链路完整可达、无过滤、终点 sink 危险形态 | static-confirmed (dataflow) | 交单漏洞 skill 收黑盒可观测效果证据 → 最终 confirmed |
| 链路可达但中间有过滤 / 白名单调用、过滤完整性需业务判定 | needs_review | 业务复核过滤逻辑;过滤不完整则降回 static-confirmed |
| 链路追到反射 / 闭源依赖 / 动态构造边界 | static-unknown | 推 dependency-decompile 反编译续追,或推动态分析 |
| 链路证明经参数化绑定 / 白名单 enum / 无 raw 通道 | not_vulnerable | — |
禁止仅凭本能力链路证明直接判 confirmed——无可观测效果证据,仅静态可达不构成动态利用。
为什么这里是「必须」:产物结构是下游机器消费的接口;聚合 / 区间 / 抽样会让 result-with-file 计数闸门失效,并让单漏洞 skill 无法回溯到具体 file:line 与跨函数链路上的中间过滤点。
每确认一条数据流发现 / 需复核项立即 append 一行规范化 jsonl 到 shared/coverage-ledger/findings/dataflow-analysis.jsonl,不等汇总阶段回头整理(why:"事后总结"是聚合 / 区间 / "等"省略的根源):
{
"id": "df-001",
"title": "request.getParameter -> JdbcTemplate.queryForObject 跨函数可达",
"severity": "high",
"cwe": "CWE-89",
"source": "request.getParameter(\"name\")",
"sink": "JdbcTemplate.queryForObject(sql, ...)",
"entry_point": "GET /user/search",
"status": "needs_review",
"confidence": "static-confirmed",
"file_location": "UserController.java:42 -> UserService.java:88 -> UserDao.java:120",
"source_report": "dataflow-analysis",
"description": "..."
}
字段约束:
id 带 df- 前缀全局唯一status ∈ confirmed | needs_review | not_vulnerable | false_positive | superseded(本能力默认 needs_review,不独立判 confirmed)confidence ∈ static-confirmed | needs_review | static-unknown | not_vulnerable(source, sink, entry_point) 三元组任一不同即各自独立成行——同一 sink 被多个入口点到达时每个入口点各一行,禁止合并折叠file_location 用 -> 连接跨函数链路(source 位置 → 中间函数 → sink 位置);单点 sink 也填具体 file:line,不留空entry_point 填该流可达的 HTTP 入口点(method+URL);无明确入口点的系统性命中填 systemic禁止:
why:本能力"链路不可达 / 已防护"结论是覆盖完整性产物声明,缺失反向验证会让下游单漏洞 skill 误信"该子系统该 sink 安全"。
写"未发现可达链路"或"已防护"前,产物必须包含:
static-unknown 单元格的具体原因(反射 / 闭源 / 动态构造 / 跨服务边界)清单不完整 → 结论降级 partial-coverage。
反例 1:SyntaxFlow 查询过宽召回大量 helper / wrapper 误报
*.exec 而不限定具体类)会把 helper、test、不可达分支都召回Runtime.*.exec 锚定后召回数百条,其中大量是测试代码 / 反射工具类调用test/ / *Test.java / MockExec 类Runtime.getRuntime().exec),或加 depth 限制,或在追踪后用文件路径过滤排除 test反例 2:source 表达匹配到了非用户可控的内部入口
request.getAttribute("x") 命中但实际值由 filter 内部设定而非用户可控request.getAttribute("internalUserId"),值由可信 filter 写入,攻击者无法直接控制setAttribute 而非 request.getParameter反例 3:框架自动转义层在 SSA 图上看不到
request.getParameter 直达 model.addAttribute 再到 Thymeleaf 模板渲染,SSA 看似无过滤;但 Thymeleaf 默认 HTML escape 让 XSS 不成立static-confirmed,但补一行 description 注明"sink 是 Thymeleaf 模板渲染、默认 HTML escape";最终判定由单漏洞 skill(如 stored-xss-detection)结合框架默认行为给出反例 4:查询过窄漏掉等价 sink
Runtime.exec 写了但 ProcessBuilder.start 没写,漏掉等价 sinkProcessBuilder().command(...).start() 启动子进程,规则只锚 Runtime.exec,命中为零ProcessBuilder 但 SyntaxFlow 报告无命中Runtime.exec + ProcessBuilder.start + Kernel32#CreateProcess;SQL:Statement.execute* + PreparedStatement.execute* + ORM raw)反例 5:项目自定义包装层未识别
CmdUtil.run(String) 内部调 Runtime.exec,规则只查 JDK API 漏报CmdUtil.run(userInput),SyntaxFlow 报告"无命令执行 sink"CmdUtil.run 加入 anchor 集合重跑;或对 CmdUtil 类先做一遍"内部是否调危险 API"扫描确认其为 sink wrapper反例 6:闭源依赖里的 sink 默默被忽略
external-lib.queryUser(name) 数据流到此为止,但 external-lib 内部用拼接unknownstatic-unknown 推 dependency-decompile 反编译后重新追内部数据流;禁止默认为 not_vulnerable白盒底线:不假装看到看不到的代码。本能力的可观测能力到 SSA 图上的可见调用边为止;下列情形必须标
static-unknown,不允许默认为 not_vulnerable。
反射 / 动态分派:
Method.invoke() / 通过字符串决定调用哪个 DAO 方法getattr(obj, method_name)(args) / eval / execobj[methodName]() / new Function(...)static-unknown,记录反射点 file:line;不替业务做"反射目标是否危险"判断闭源 / 无源码依赖:
unknown → 走 dependency-decompile 反编译恢复源码 → 在反编译产物上重新跑本能力续追内部数据流;反编译恢复后续追时,若污点跨入产物内部新引用的无源码依赖,同样回 dependency-decompile triage——别停在第一层动态字符串构造:
config.get("query.user") 然后执行)Template.evaluate(string))static-unknown,记录配置 / 模板位置;如有必要读实际配置文件验证;推 dynamic analysis跨服务 / 跨进程边界:
AOP / 注解处理器 / 框架自动注入:
@Aspect 拦截器在 sink 调用前后插入逻辑运行时配置切换 / feature flag:
SSA 编译失败 / 语言不支持:
ssa_compile 失败 / 语言暂不支持rg 入口盘点 + 参数角色盘点 + 固定 checklist),禁止直接判"无可达链路"底线:本能力写"该 (source, sink) 对无可达链路"前,所有 static-unknown 单元格必须显式列出原因(反射点 file:line / 闭源依赖名 / 动态构造位置 / 跨服务出站调用点)。否则结论降级 partial-coverage。
本能力 n/a(原因:本能力是跨漏洞数据流工具,不对单类漏洞修复负责。修复路径见对应单漏洞 skill 的 §12:SQL 注入修复 → 参 sast-scan 协作的 SQL 注入审计能力下游 skill;命令注入修复 → 对应能力;XSS 修复 → stored-xss-detection §12;反序列化修复 → 对应能力。本能力只提供"链路证明"素材,让单漏洞 skill 在制定修复时知道该修哪一段链路——上游 source 加白名单还是 sink 上加参数化绑定)。