mcpField
G
gitnexus-taint-analysis

gitnexus-taint-analysis

github.com/abhigyanpatwari开发48.1k347 次安装今天更新
代码仓库

关于 gitnexus-taint-analysis

面向 GitNexus `--pdg` 控制流与污点分析子系统开发者的技能,说明分析流程、设计约束、已知局限和验证步骤。

主要功能

  1. 01CFG 与到达定义设计
  2. 02过程内与过程间污点分析
  3. 03源、汇与净化器建模
  4. 04已知漏报类型
  5. 05`--pdg` 变更验证清单

适用场景

  1. 01追查污点流为何被报告或遗漏
  2. 02为特定语言添加源或净化器
  3. 03审查 CFG 或污点分析实现变更

MCP 相关

说明如何解读 GitNexus 的 `explain` MCP 工具结果,包括过程内与过程间污点发现。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/abhigyanpatwari/gitnexus --skill gitnexus-taint-analysis

安装后在 Claude Code 中输入/gitnexus-taint-analysis确认已加载。

详细介绍

使用 GitNexus 进行 CFG 与污点分析

针对可选启用的 --pdg 程序分析子系统的专家知识:控制流图、可达定义以及过程内 + 过程间污点分析。在接触 gitnexus/src/core/ingestion/cfg/** 或 gitnexus/src/core/ingestion/taint/** 之前,或在解释某项发现时,请先阅读本文。

何时使用

  • “污点引擎是如何工作的 / 为什么这条流(未)被报告?”
  • 向模型中添加 source、sink 或 sanitizer。
  • 扩展或审查 CFG / reaching-defs / 污点 / summary 代码。
  • 理解 explain MCP 工具的发现(过程内 vs 过程间)。
  • 调试 --pdg 输出中的误报或漏报。

分层基底(构建顺序)

污点分析运行在图之上,而非与之并列。每一层都通过 --pdg 可选启用,默认的 analyze 运行是字节级完全相同的(黄金一致性门禁是这里每一项变更的硬性底线)。

L1  CFG            per-function basic blocks + control-flow edges   (M1 #2081)
L2  REACHING_DEF   GEN/KILL def→use data dependence (pure solver)   (M2 #2082)
L3  Taint (intra)  source→sink over RD facts, minus sanitizers      (M3 #2083)
L4  Taint (inter)  per-function summaries composed over CALLS       (M4 #2084)
  • Worker 构建,主线程求解。 解析 worker 构建每个函数的 CFG + 采集 def/use + 调用点事实到 ParsedFile.cfgSideChannel (纯数据,可安全进行结构化克隆 —— 绝不是 AST 节点)。主线程运行纯求解器。绝不在主线程重新解析(会重新引入 #1983 的 OOM)。
  • 阶段内发射(KTD1)。 L1–L4-harvest 全部运行在作用域解析的 pdg 窗口内(scope-resolution/pipeline/run.ts,由 input.pdg === true 门控),因为该阶段结束时基于磁盘的 ParsedFile 存储会被清空 —— 一个独立的 post-mro 阶段会读到空数据。跨函数不动点(L4)是例外:它运行在自己注册的阶段(taintSummaries)中,位于作用域解析之后,因为它需要完整的调用图,并消费通过 ScopeResolutionOutput 传递出来的小型纯 summary 数据。
  • 纯求解器契约。 computeReachingDefs、computeTaintFlows、 harvestFunctionSummary 和 solveInterprocTaint 是纯函数且确定性的 (无图、无 I/O、无日志器;输出已排序)。快照测试和基于内容派生的边 id 依赖于此。

过程内污点分析(L3)

在 RD 事实上从匹配的 source 到匹配的 sink 进行前向可达性分析,被 sanitizer 消除。值得内化的关键设计要点:

  • 带出现位置的 site 标记。 扁平的按参数绑定集合无法区分 exec(escape(x))(安全)和 exec(x)(发现);采集器记录嵌套调用结构(SiteRecord.parent/via 标记),因此 sanitizer 的介入是精确的。
  • 类型集合 sanitizer 模型。 污点携带一组已中和的 SinkKind;除非 sink 的类型在该集合中,否则该 sink 会触发。因此 escape(req.body) 会抑制 res.send(xss),但仍然会触发 db.query(sql)—— 类型盲消除会导致被抑制的实时注入(禁止的漏报方向)。 path.basename(t) 仅中和路径穿越,而不中和命令注入。
  • 语句级发现身份。 不是块对(块合并会丢失不同发现;exec(req.body, req.query) 是两项发现)。
  • 持久化为 TAINTED 边(BasicBlock→BasicBlock);路径通过共享的版本化编解码器(taint/path-codec.ts)搭载在 reason 列上。

过程间污点分析(L4)——函数式/摘要方法

生产级方法(Sharir-Pnueli 1981;与 Meta 的 Pysa 和 Mariana Trench,以及 FB Infer 形态相同)——而非完整的 IFDS 制表。每个函数被归约为一个紧凑的摘要,摘要在已解析的 CALLS 图上进行组合。

摘要形态(taint/summary-model.ts,整参数粒度):

边含义类比
param→return参数流向返回值TITO——保留(下限已覆盖其召回率;精度处理推迟)
param→callee-arg参数流入调用的第 j 个实参(携带路径中被中和的 sink 类型)TITO 进入被调用者
param→sink参数到达一个已建模的 sink部分/触发的 sink
source→return函数生成并返回一个 source生成式——通过调用者的 callResults 组合
source→callee-arg生成的 source 流入一次调用不动点 SEED
callResults用户函数调用的结果流向调用者中的 sink/return/callee-arg与被调用者的 source→return 组合

不动点(taint/interproc-solver.ts):单元是 (function, parameter, source)。从 source→callee-arg 播种,通过 param→callee-arg 传播,当受污参数遇到 param→sink 时触发一个发现。

  • 通过单调性实现循环安全。 受污集合在有限格(fn × param × source)上是单调的,因此工作列表会收敛——递归调用只是重新提议一个已访问过的条目。SCC 缩并只会细化处理顺序;正确性/终止性并不需要它。
  • 按 source 区分的状态(关键承载)。 状态也以 SOURCE 为键。仅以 (fn, param) 为键会合并多源流:被 source A 污染的 sink 参数被标记为已访问,而之后来自 source B 的流在触发前被丢弃——这是反复出现的多源 bug 类别。(Bit M3;bit M4 U9。)
  • 基于名称的调用连接。 将摘要的 call-arg 边与 CALLS 边按被调用者名称匹配,而非按调用点行号——基于行的对齐(CFG 从 1 开始 vs 引用位置)很脆弱;被调用者身份是精确的,而上下文不敏感会在每个调用点以相同方式污染被调用者的参数。
  • 持久化为 TAINT_PATH 边(Function→Function),reason 中的函数级跳转链通过同一编解码器;置信度 < 过程内的 1.0。

上下文不敏感是此层级可接受的权衡:每个函数一个摘要,接受返回值/调用点合并(安全保守)。预期合并会产生一些 FP;更大的 FN 来源是未建模的特性(见下)。

已知假阴性类别(已记录,推迟)

最大的是闭包/回调(arr.forEach(() => sink(y)))——没有按库的模型时,进入回调的污点会被丢弃(CodeQL 的 JS 库也是如此)。同样推迟的还有:字段/属性流(obj.x = taint; sink(obj.y))、字段敏感的访问路径、守卫式净化器、隐式/控制依赖流、promise/async-await 线程化,以及受污简单参数之前的解构/剩余参数(摘要端口索引是绑定序号,而非形参位置——需要从 worker 的 BindingEntry 贯穿一个形参索引)。过程间连接也是上下文不敏感的:当一个调用者调用两个不同的同名被调用者时,流入其中一个的流会被过度归因到两者(健全——过度报告,绝不会遗漏流)。没有发现并不能证明安全。

GitNexus 特有的注意事项

  • 函数与 CFG 的连接。 FunctionCfg.functionStartLine 从 1 开始;Function/ Method 节点的 startLine 从 0 开始——通过 startLine - 1 连接。函数节点 没有列号,因此同一行的函数({a:()=>x(), b:()=>y()})无法区分 → 应丢弃 (摘要驱动程序会统计 unresolved),而不是错误连接。
  • 没有关系属性索引(S1)。 Kuzu 没有关系属性的二级索引,而无锚点的 [:TAINTED*]/[:TAINT_PATH*] 查询会导致查询量暴增。因此,TAINT_PATH 会在 分析时物化并设置锚点,绝不进行实时遍历;explain 会读取带源锚点且受 LIMIT 保护的数据。
  • explain 是唯一的发现入口。 TAINTED/TAINT_PATH 被刻意排除在 VALID_RELATION_TYPES(impact 的允许列表)和 Web 架构之外(固定于 security.test.ts)。explain 会枚举这两层(跨函数发现结果带有 interprocedural: true)。
  • 共用一个编解码器。 发射路径和 explain 都导入 taint/path-codec.ts。两份手写的线格式副本会逐渐不一致——绝不要拆分。 当写入器和读取器同时发布时,新元数据应在同一版本内扩展格式。
  • 缓存兼容性。 Worker 收集逻辑变更会通过 PDG 构件标识自动使缓存失效。 将仅用于提取的依赖项保留在 PDG 所有权边界内,并验证普通解析键保持稳定。 共享解析器的变更属于基础标识。持久化图/配置变更会通过 RepoMeta.pdg 的键集合不匹配触发完整回写。模型内容由 taintModelVersion 管理。

添加 source / sink / sanitizer

污点模型覆盖三个文件中的四个 SupportedLanguages ID:TypeScript 和 JavaScript 使用 taint/typescript-model.ts,Python 使用 taint/python-model.ts,Java 使用 taint/java-model.ts。请编辑目标语言对应的模型。typescript-model.ts 中显式的 registerBuiltinTaintModels 接口会注册全部四种模型;它不是导入副作用。

规范是可哈希的数据(不含函数)。sanitizer 的 neutralizes 会列出其防护的 确切 sink 类型——绝不能笼统地清除全部污点。在 test/unit/taint/ 中添加测试样例 并断言发现结果(或未发现结果)。TypeScript 和 JavaScript 使用真实源码测试框架 test/helpers/ts-cfg-harness.ts;Python 和 Java 的模型匹配由 python-model-match.test.ts 和 java-model-match.test.ts 覆盖。端到端验证位于 test/integration/cfg/。

任何 --pdg 变更的验证清单

1. tsc clean (schema additions are exhaustiveness-checked; watch the
   api.ts getNodeQuery runtime read-path if a node label is added).
2. Targeted vitest by directory (test/unit/taint, test/unit/cfg,
   test/integration/cfg) — verify by ISOLATION, not full-suite exit
   (known load-flakes). `node scripts/build.js` before worker/integration runs.
3. Flag-off golden byte-identical (pipeline-graph-golden.test.ts).
4. bench/cfg/measure.mjs --check (no fingerprint drift / budget regression).
5. detect_changes() before commit; impact({direction:'upstream'}) before
   editing shared symbols (KnowledgeGraph, RepoMeta, RelationshipType, codec).

先前研究(深入设计问题时参考)

Sharir & Pnueli 1981(函数式方法);Reps-Horwitz-Sagiv IFDS(POPL 1995); FlowDroid/StubDroid(访问路径摘要);Pysa & Mariana Trench(TITO / 传播,并行 SCC 不动点);CodeQL Models-as-Data(最丰富的端口表示法,包括回调端口); Infer(基于内容键的增量摘要)。

评论

支持 Markdown