Open
[Bug]-Actions runner 将 PR 正文文本拼接进 shell 脚本,提交者可控内容会被求值执行 #2226
Wang HengAdd on 14 days ago
AtomGit小助手
13 days ago Comments:
13 days ago Comments:
您好,感谢您的反馈,该问题目前已经反馈技术进行核实,感谢您的耐心等待。


AtomGit小助手
11 days ago Comments:
11 days ago Comments:
感谢您的详细漏洞报告,我们已经将问题给到技术团队核实处理,现回复如下:
- __ATOMGIT_CONTEXT_DATA__属于内部调试用变量,并未对外文档公开,下个版本我们会移除该变量,相关业务数据请使用标准 atomgit 上下文对象获取。
- 针对 pull_request 事件场景,我们会对所有用户可控输入做审计校验;workflow 执行基于源分支 commitId 或者预合并代码运行,后续会落地对应的安全审核防护机制,防范恶意代码注入风险。
- 根因在于 runner 侧脚本拼接实现,我们正在修复该逻辑,避免不可信用户输入直接被 shell 解析执行。


环境
0.0.4.10.version,镜像ubuntu-latest现象
Runner 执行
run:步骤时,会把运行上下文(暴露为环境变量__ATOMGIT_CONTEXT_DATA__)的内容以文本方式拼接进即将执行的 shell 脚本,而不是作为一个正确引用的环境变量传递给 bash。该上下文包含 Pull Request 的
title与body——由提交者完全控制的字段。因此,当某个 workflow 步骤在脚本里引用了这个变量,PR 正文中的 shell 元字符会被 bash 按语法解释,而不是当作数据处理。
日志证据
某步骤脚本中有一行形如
echo "$__ATOMGIT_CONTEXT_DATA__" | ...的语句。该 PR 的正文里有若干处用 Markdown 反引号包起来的普通说明文字。构建日志随即出现:每一条都逐字对应 PR 正文中被反引号包围的内容。
同一份日志里另有一条
fatal: could not read Username for 'https://gitcode.com',对应正文里被反引号包围的一条 git 命令——它确实被执行了,只是因为 checkout 步骤已清除凭据而失败。也就是说:这些字符串没有被当成数据打印,而是被 shell 当成命令求值了。报错中的
line 8正指向脚本里引用该上下文的那一行。影响
任何能对目标仓库发起 Pull Request 的人,只要该仓库某个 workflow 在 shell 步骤里引用了上述上下文变量,即可让自己控制的文本在构建机上以 runner 权限被求值。
需要评估的后续影响面:
http.extraheader,步骤结束前才Removing auth,在此之前存在凭据可用窗口)触发不需要仓库写权限,也不需要 PR 被合并——CI 在 PR 打开时即运行。
复现条件
on: pull_request的 workflowrun:步骤在脚本中引用了__ATOMGIT_CONTEXT_DATA__满足以上条件时,日志中会出现这些文本被求值的痕迹。本报告不提供可直接使用的利用载荷。
建议的修复方向
根因是上下文数据以文本替换方式进入脚本,跨越了「数据」与「代码」的边界。
.env文件后由 shell 读取,而不是拼接export VAR=<原始内容>title、body、分支名、提交信息等应视为不可信输入,与 runner 自身元数据分开处理$(...)、;、换行),确认日志中它们被原样输出而非求值报告方已采取的缓解
我方 workflow 中已停止使用
$__ATOMGIT_CONTEXT_DATA__展开,改用printenv __ATOMGIT_CONTEXT_DATA__取值,以避开文本替换路径。此缓解仅对我方自己的 workflow 有效,不构成对该问题的修复。
补充
如贵方有专门的安全响应渠道,我方乐意配合把细节转到私密渠道,并按贵方披露政策约定公开时间。此处提交是因为未找到公开的安全报告入口。