Coordinated Disclosure Timeline

Summary

Excalidraw is vulnerable to Poisoned Pipeline Execution (PPE) on its autorelease-preview.yml workflow allowing an external attacker to gain write access to the repository.

Project

Excalidraw

Tested Version

Latest commit at the time of reporting

Details

Execution of untrusted code in autorelease-preview.yml (GHSL-2024-158)

The autorelease-preview.yml workflow is triggered on issue_comment events, that is when anyone comments on an Issue or Pull Request. Specifically, it only triggers when the comment is @excalibot trigger release and the issue is a Pull Request:

if: github.event.comment.body == '@excalibot trigger release' && github.event.issue.pull_request

The workflow runs with default write-all permissions and has access to secrets.

Taking the above into account, the workflow, checkouts the HEAD reference of the commented Pull Request which allow an attacker to introduce arbitrary files into the GitHub’s runner:

- name: Get PR SHA
  id: sha
  uses: actions/github-script@v4
  with:
    result-encoding: string
    script: |
      const { owner, repo, number } = context.issue;
      const pr = await github.pulls.get({
        owner,
        repo,
        pull_number: number,
      });
      return pr.data.head.sha
- uses: actions/checkout@v2
  with:
    ref: ${{ steps.sha.outputs.result }}
    fetch-depth: 2

Later, the workflow calls yarn autorelease preview which would run arbitrary code since the attacker can control the package.json file.

- name: Auto release preview
  id: "autorelease"
  run: |
    yarn add @actions/core -W
    yarn autorelease preview ${{ github.event.issue.number }}

PoC

...
  "scripts": {
...
    "autorelease": "echo POISONED",
    "prerelease:excalidraw": "node scripts/prerelease.js",
    "build:preview": "yarn build && vite preview --port 5000",
    "release:excalidraw": "node scripts/release.js"
  }
}

Impact

An attacker may be able to gain write access to the repository and the secrets.NPM_TOKEN secret.

Resources

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