TRAE-security-review

TraeWork 内置 skill —— 执行代码安全扫描。审查合并请求和代码差异,提供结构化的安全漏洞风险反馈。核心原则:Right-side line numbers only + Confidence floor = 0.8——不能明确证明可利用就别报告。


一、定位

字段值
所属TraeWork 内置 skill(安全审查)
触发条件审查 MR / PR / 代码 diff,提供安全反馈
核心方法3 遍审计(项目基线 / 偏差地图 / 源到汇追踪)
核心理念Reportable ⇔ Demonstrably exploitable(可报告 ⇔ 可证明可利用)

二、7 条不可违反的运行原则

  1. Right-side line numbers only — 位置都是变更后的行号。变更前的行号无效。
  2. Range form [L_start, L_end] — 单行问题 start 和 end 相同。
  3. Diff-introduced surface only — 变更前就有且没改的弱点不在范围内。
  4. Reportable ⇔ Demonstrably exploitable — 不能说出 (a) 攻击者控制的输入从哪进 (b) 到哪个危险 sink/边界,就别报告。
  5. 默认排除:可用性 / DoS、限流、代码风格、测试/fixture 代码
  6. Confidence floor = 0.8 — 低于 0.8 → 丢弃,或交给下游过滤 / 人工审查
  7. No patches — 识别 + 解释。报告里别写替换代码。

三、9 步流程

3.1 范围决议(§1)

3.1.1 用户已经指定了范围

完全用用户的原话——不扩大不缩小。

3.1.2 范围缺失或模糊

用 AskUserQuestion 工具,给 4 个选项:

  1. 当前工作区的 uncommitted / staged changes
  2. 相对命名 branch 的 diff(问 branch 名)
  3. 特定的 MR / PR(问标识符)
  4. 给定文件列表(问路径)

如果 AskUserQuestion 不可用,把这 4 个选项用纯文本问。

3.1.3 默认回退

如果用户拒绝指定并要你继续,审计 branch-vs-origin/HEAD delta——用 §2 的数据采集链。

3.2 Diff 数据采集(§2)

跑 4 个 probe——它们是审计的权威输入:

Probe命令用途
Working tree stategit status检测 untracked / staged 异常
Touched filesgit diff --name-only origin/HEAD...枚举文件 surface
Commit timelinegit log --no-decorate origin/HEAD...跨 commit 重建意图
Authoritative diffgit diff --merge-base origin/HEAD变更内容的唯一权威源

最后一个 probe 产生的 diff 是唯一权威变更内容。聊天里的内联片段是建议;diff 覆盖。

3.2.1 Probe 失败级联

如果 merge-base diff 失败,按这个顺序试:

  1. git diff origin/HEAD...
  2. git diff HEAD~1
  3. git diff(工作区)
  4. 用 AskUserQuestion 让用户明确范围

如果单个辅助工具(如 SearchCodebase)间歇性不可用,继续剩下的部分,显式标记结论受证据范围限制。

3.3 上下文采集(强制,§3)

禁止只基于片段推理。每个候选发现必须按这个顺序收集仓库级证据:

  1. 确认范围(§1)
  2. 采集 diff + commits(§2)
  3. 用 SearchCodebase 定位 (a) 输入入口 / 信任边界 (b) 项目已有的 sanitizer / validator / authZ helper
  4. 用 Read 检视触碰文件的完整 body + 相关的调用链邻居
  5. 上面都完成后才开始起草发现

每个候选发现必须收集:

  • Source-side evidence — 执行路径上具体的攻击者控制入口
  • Sink-side evidence — 输入到达的危险操作、安全边界跨越、敏感数据暴露
  • Bypass-context evidence — 附近代码是否已经 sanitize / encode / validate / authorize;项目已有的 helper 是否中和了问题

如果 source-side 或 sink-side 无法用仓库代码证实,丢弃这个发现。

3.4 作者意图重建(§4)

在把任何东西归类为漏洞之前,推断作者写这个 diff 的原因。编辑模式常常能消除意图的歧义:

  • 新的错误处理 / null-guards → 防御性重构,提高 “missing-validation” 发现的门槛
  • 算法或数据结构替换 → 行为变化;检查调用者的不变量
  • 依赖升级 + adapter 粘合 → API 形状迁移;检查旧的安全假设是否还成立
  • 变量 / 模块重命名 → 低语义变化;通常没有安全 delta

把推断的意图当作一句话总结,用作候选发现模糊时的决胜点:和明显防御性意图矛盾的发现需要更多证据,不是更少。

3.5 漏洞面(§5)

只审计下面的类别。每个类别列出算数的模式;不在列表里的除非组合了这些,否则不在范围内。

5.1 不受信输入处理

  • 通过未净化值的 SQL 注入
  • 子进程 / shell-out 路径中的 OS 命令注入
  • XML 解析器中的 XXE
  • 服务端模板注入
  • NoSQL 查询注入
  • 文件系统操作中的路径遍历

5.2 认证 / 授权缺陷

  • 通过有缺陷的谓词逻辑绕过认证
  • 垂直 / 水平权限提升
  • 失效的 session 生命周期:fixation、logout 后复用、缺少 rotation
  • JWT 误用:弱密钥、alg=none、缺少 aud / iss / exp 检查
  • 对象级访问缺口(IDOR 类)

5.3 加密和密钥处理

  • 源码中的硬编码密钥 / 密码 / token
  • 使用损坏或减弱的算法(MD5、SHA1、ECB、RC4、…)
  • 不安全的密钥持久化或传输
  • 安全上下文中的可预测随机性(Math.random、非 CSPRNG)
  • 禁用或存根的证书验证

5.4 代码执行和注入

  • 通过不安全的反序列化(pickle、ObjectInputStream、…)实现远程代码执行
  • 实例化任意类型的 YAML loader(不带 SafeLoader 的 yaml.load)
  • 不受信字符串上的 eval / Function / exec
  • Web 表面中的 XSS — 反射 / 存储 / DOM

5.5 敏感数据暴露

  • 秘密、凭据或 PII 写入日志或持久存储
  • 端点响应返回的内容超出消费者应看到的
  • 生产路径上的调试 / 栈 / 构建信息泄露

Local-network-only 可利用性不降低严重性。local-only RCE 仍然是 HIGH。

3.6 审计程序(§6)

3 遍,按顺序。不要交叉。

  • Pass A — 项目安全基线:识别项目已有的安全原语:哪些 validators、escapers、ORM、auth middleware、crypto wrappers 在用。项目自己的模式是比较基线。

  • Pass B — 偏差地图:对每个触碰的文件问:新代码用了项目已有的原语,还是引入了绕开它们的新 ad-hoc 处理?偏差是最高产的发现来源。

  • Pass C — 源到汇追踪:对每个可疑点追踪控制 / 数据流:

    • 值从哪进
    • 跨过哪些边界
    • 路径上是否有 encoding / validation / authZ 检查
    • 落在哪

没通过 Pass C 的就丢。

3.7 严重性 & 置信度(§7)

3.7.1 严重性等级

严重性触发
HIGH直接可利用:RCE、authN 绕过、大范围数据泄露、垂直权限提升
MEDIUM在特定但现实的条件下可利用,有实质影响
LOW纵深防御缺口,直接影响边际。仅在链条具体时报告

3.7.2 置信度

范围含义行动
0.90 - 1.00具体攻击路径,仓库内可端到端追踪报告
0.80 - 0.89识别的易损模式,前置条件看起来可满足报告
0.70 - 0.79怀疑形状,前置条件投机丢弃
< 0.70投机丢弃

偏向假阴性。漏掉边缘发现比洪水报告好;噪音报告比漏掉纵深防御问题更快摧毁审查者信任。

3.8 硬性排除(§8)

这些不能逐个发现豁免。

3.8.1 范围外(按类别)

  • 可用性:DoS、资源耗尽、限流缺口、内存 / CPU 压力
  • 过时的第三方依赖(由单独工具处理)
  • 文档文件里的发现(*.md、设计文档、RFC)
  • 「缺少审计日志」/ 「缺少加固」 — 单独不构成漏洞
  • 单元测试或 fixture 代码里的发现
  • 没有具体可达路径的 race / TOCTOU 模式
  • 任何形式的 Regex 注入和 ReDoS
  • 包含未净化用户输入的日志条目(「日志欺骗」);只有日志中的 secrets / credentials / PII 算数
  • 在 AI 系统 prompt 里包含用户控制的内容
  • 只控制 URL path 的 SSRF;SSRF 只在 host 或 protocol 可影响时算

3.8.2 框架和语言豁免

  • React / Angular / Vue 默认 XSS-safe。发现需要明确的 escape hatch — dangerouslySetInnerHTML、bypassSecurityTrust*、v-html 或等价的
  • 客户端 JS / TS 里缺少 authN / authZ 不是漏洞;那些检查在服务器上
  • 内存安全语言(Rust、Go、managed JVM/CLR/JS)中的内存安全问题(buffer overflow、UAF、double free)不报告
  • Shell 脚本中的命令注入默认不可达;需要可证明的不受信输入入口
  • *.ipynb 默认不可达;证据门槛和 shell 脚本相同
  • 环境变量和 CLI flag 是受信输入 — 任何依赖攻击者控制 env / flag 的链条无效
  • UUID 不可猜;不要标记缺少 UUID 验证
  • GitHub Actions workflow 问题在报告前需要明确的不受信 trigger 路径

3.8.3 微妙的 Web bug

Tabnabbing、XS-Leaks、原型污染、open redirect — 只在利用链高置信度且端到端可见时。默认丢弃。

3.8.4 日志先例

  • 记录 URL 是安全的
  • 记录非 PII 业务值是安全的,即使值「感觉」敏感
  • 只有暴露 secrets / credentials / PII 的日志条目可报告

3.9 输出(§9)

3.9.1 干净的 diff

如果 §3-§8 后没有东西,输出一行总结:

✅ No exploitable issues found in the reviewed change set.

3.9.2 发现表

否则,精确输出一张表:

#CategoryTitleSeverityConfidenceEvidence (Source → Sink)RecommendationLocation
1sql_injectionConcatenated query in lookup_userHIGH0.92req.query.q (router L17) → string concat → db.query (svc L88)Switch to parameterized query via the project’s existing db.safe_query helperservices/user.py:[80, 95]

列规则:

  • Category 用 §5 的 snake_case 分类法(如 xxe、idor、unsafe_deserialization、weak_crypto)
  • Severity ∈ {HIGH、MEDIUM、LOW} 按 §7.1
  • Confidence 是数字值,保留两位小数
  • Evidence 必须编码 source 和 sink;→ 分隔
  • Location 用右侧行范围 + file:///…#Lstart-Lend 链接形式
  • Recommendation 是散文,不写代码。不写 patch。

发现按严重性降序排,然后置信度降序。

3.10 发出前最终自检(§10)

跑这个清单;任何项不通过就删除该行。

  1. 行的 location 用了变更后的行号?
  2. 问题是这次 diff 引入或恶化的,不是预先存在且没碰的?
  3. Evidence 单元格里有 source 和 sink?
  4. Confidence ≥ 0.80?
  5. 行通过了 §8 的所有硬性排除?
  6. Recommendation 只有散文,没有代码 patch?

任何「否」→ 删行再发出。


四、与其他 skill 的关系

Skill关系
triage安全审查是 issue 分流的一部分
diagnosing-bugs修发现的 bug
tdd写回归测试防漏洞复发

五、引用来源

  • TraeWork 实际 skill 路径 —— 本文内容完全来自此文件

六、一句话总结

TRAE-security-review 是「代码安全审查」技能——核心是「能证明可利用才能报告」+ Confidence ≥ 0.8 + 报告里不写 patch。报告是发现 + 证据 + 建议(散文),不是修复方案——避免假阴比避免噪音更重要。