Coordinated Disclosure Timeline
协调披露时间表
- 2023-12-18: Opened GHSA-mcph-m25j-8j63 through Private Vulnerability Reporting
2023-12-18:通过私有漏洞报告开放GHSA-mcph-m25j-8j63 - 2023-12-22: Fixed in 0102c07
2023-12-22:已在 0102c07 中修复
Summary 总结
The tj-actions/changed-files
workflow allows for command injection in changed filenames, allowing an attacker to execute arbitrary code and potentially leak secrets.
该 tj-actions/changed-files
工作流允许在更改的文件名中注入命令,从而允许攻击者执行任意代码并可能泄露机密。
Project 项目
changed-files 更改的文件
Tested Version 测试版本
Details 详
Potential Actions command injection in output filenames (GHSL-2023-271
)
输出文件名中的潜在操作命令注入 ( GHSL-2023-271
)
The changed-files
workflow returns the list of files changed in a commit or pull request.
changed-files
工作流返回提交或拉取请求中更改的文件列表。
const allChangedFiles = await getChangeTypeFiles({
inputs,
changedFiles: allFilteredDiffFiles,
changeTypes: [
ChangeTypeEnum.Added,
ChangeTypeEnum.Copied,
ChangeTypeEnum.Modified,
ChangeTypeEnum.Renamed
]
})
core.debug(`All changed files: ${JSON.stringify(allChangedFiles)}`)
await setOutput({
key: getOutputKey('all_changed_files', outputPrefix),
value: allChangedFiles.paths,
writeOutputFiles: inputs.writeOutputFiles,
outputDir: inputs.outputDir,
json: inputs.json,
shouldEscape: inputs.escapeJson
})
Even though there is a shouldEscape
option enabled by default, it only escapes "
for JSON values. The setOutput
function is defined as follows:
即使默认情况下启用了一个 shouldEscape
选项,它也只会 "
对 JSON 值进行转义。该 setOutput
函数定义如下:
export const setOutput = async ({
key,
value,
writeOutputFiles,
outputDir,
json = false,
shouldEscape = false
}: {
key: string
value: string | string[] | boolean
writeOutputFiles: boolean
outputDir: string
json?: boolean
shouldEscape?: boolean
}): Promise<void> => {
let cleanedValue
if (json) {
cleanedValue = jsonOutput({value, shouldEscape})
} else {
cleanedValue = value.toString().trim()
}
core.setOutput(key, cleanedValue)
...
}
The jsonOutput
function is defined as follows:
该 jsonOutput
函数定义如下:
export const jsonOutput = ({
value,
shouldEscape
}: {
value: string | string[] | boolean
shouldEscape: boolean
}): string => {
const result = JSON.stringify(value)
return shouldEscape ? result.replace(/"/g, '\\"') : result
}
This allows filenames to contain special characters such as ;
and ` (backtick) which can be used by an attacker to take over the GitHub Runner if the output value is used in a raw fashion (thus being directly replaced before execution) inside a run
block. By running custom commands an attacker may be able to steal secrets such as GITHUB_TOKEN
if triggered on other events than pull_request
. For example on push
.
这允许文件名包含特殊字符,例如 ;
‘(反引号),如果输出值在 run
块内以原始方式使用(因此在执行前直接替换),攻击者可以使用这些字符来接管 GitHub Runner。通过运行自定义命令,攻击者可能能够窃取机密,例如 GITHUB_TOKEN
在除 pull_request
.例如,在 push
上。
Proof of Concept 概念验证
In the case of a repository containing the following workflow, as detailed in changed-files
README:
对于包含以下工作流的存储库,如 README 中 changed-files
所述:
name: CI
on:
pull_request:
branches:
- main
jobs:
changed_files:
runs-on: ubuntu-latest
name: Test changed-files
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Example 1
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v40
- name: List all changed files
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
echo "$file was changed"
done
- Submit a pull request to the repository with a new file injecting a command. For example
$(whoami).txt
would be a valid filename.
使用注入命令的新文件向存储库提交拉取请求。例如$(whoami).txt
,将是一个有效的文件名。 - Upon approval of the workflow (triggered by the pull request), the action will get executed and the malicious pull request filename will flow into the
List all changed files
step.
在批准工作流(由拉取请求触发)后,将执行该操作,恶意拉取请求文件名将流入该List all changed files
步骤。
##[group]Run for file in $(whoami).txt; do
for file in $(whoami).txt; do
echo "$file was changed"
done
shell: /usr/bin/bash -e {0}
##[endgroup]
runner.txt was changed
Impact 冲击
This issue may lead to arbitrary command execution in the GitHub Runner.
此问题可能会导致在 GitHub Runner 中执行任意命令。
Credit 信用
This issue was discovered by @jsoref (Josh Soref) and reported by GHSL team member @jorgectf (Jorge Rosillo).
此问题由 @jsoref (Josh Soref) 发现,并由 GHSL 团队成员 @jorgectf (Jorge Rosillo) 报告。
Contact 联系
You can contact the GHSL team at [email protected]
, please include a reference to GHSL-2023-271
in any communication regarding this issue.
您可以通过以下方式 [email protected]
联系 GHSL 团队,请在有关此问题的任何通信中注明。 GHSL-2023-271
原文始发于GitHub Security Lab:GHSL-2023-271: Arbitrary command execution in changed-files
转载请注明:GHSL-2023-271: Arbitrary command execution in changed-files | CTF导航