Summary
Workflow runs with full write permissions, check-types.yml unsafely checks out attacker's submitted code, and then runs it.
Details
PoC
- Create a private repository containing the contents of cal.com
- Change https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L8 to
ubuntu-latest (or you could wire up a custom runner if you want to give GitHub more money, that's a bad use of money)
- Create a branch
- Change https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/package.json#L73 to run something exciting
touch a; git add a; git config user.name user; git config user.email hello@example.com; git push origin HEAD:main
- Push the branch to your private repository
- Create a PR from your private repository to your private repository's main branch
Note that it isn't possible to safely test this in public but there is nothing in the code flow that's blocking a fork from doing this as the pull_request_target has removed the permissions block.
So, what's happening...
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/pr.yml#L4-L6
Selects the target and default permissions (this repository defaults to write, you could set it to read only, but that wouldn't do what you want).
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/pr.yml#L18-L21 passes permissions down.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L10
performs a safe checkout because checkout defaults to being cautious
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L11 is as it says, dangerous.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/actions/dangerous-git-checkout/action.yml#L6-L10
now you've checked out the attacker's code.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L12
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/actions/yarn-install/action.yml#L62
This does a yarn install, which isn't terribly exciting.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L19
now we run the attacker's command.
Impact
The repository's contents are compromised.
The GITHUB_TOKEN can merge PRs, mutate them, add / delete comments, push commits to the repository, delete branches from the repository, force-push over branches in the repository.
Unless you have lots of other machinery guarding against things, which seems unlikely (and the github token can often undo that machinery).
Note that it's likely there are other workflows that can also be attacked.
In general, you're going to want to split your workflows into multiple jobs, some with contents:read (the stuff that runs untrusted content), and others w/ and use an artifact or similar to transfer data between them so that you control what data is processed by the side with write permissions.
Summary
Workflow runs with full write permissions, check-types.yml unsafely checks out attacker's submitted code, and then runs it.
Details
PoC
ubuntu-latest(or you could wire up a custom runner if you want to give GitHub more money, that's a bad use of money)touch a; git add a; git config user.name user; git config user.email hello@example.com; git push origin HEAD:mainNote that it isn't possible to safely test this in public but there is nothing in the code flow that's blocking a fork from doing this as the
pull_request_targethas removed the permissions block.So, what's happening...
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/pr.yml#L4-L6
Selects the target and default permissions (this repository defaults to write, you could set it to read only, but that wouldn't do what you want).
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/pr.yml#L18-L21 passes permissions down.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L10
performs a safe checkout because checkout defaults to being cautious
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L11 is as it says, dangerous.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/actions/dangerous-git-checkout/action.yml#L6-L10
now you've checked out the attacker's code.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L12
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/actions/yarn-install/action.yml#L62
This does a yarn install, which isn't terribly exciting.
https://github.com/calcom/cal.com/blob/9aa60fae41a6b6b101c86bf430754b439f440871/.github/workflows/check-types.yml#L19
now we run the attacker's command.
Impact
The repository's contents are compromised.
The GITHUB_TOKEN can merge PRs, mutate them, add / delete comments, push commits to the repository, delete branches from the repository, force-push over branches in the repository.
Unless you have lots of other machinery guarding against things, which seems unlikely (and the github token can often undo that machinery).
Note that it's likely there are other workflows that can also be attacked.
In general, you're going to want to split your workflows into multiple jobs, some with contents:read (the stuff that runs untrusted content), and others w/ and use an artifact or similar to transfer data between them so that you control what data is processed by the side with write permissions.