I'm trying to understand the security model in Github Actions (GHA). Let's say I have the following requirements on a public repo:
In order for the third requirement to work, the pull request needs access to the GITHUB_TOKEN with repo write permissions. This will require the following two permissions:
Now if write tokens are sent to the Workflows in fork PRs, what's to prevent a hacker from changing the Workflow in the PR and using it for any number of malicious purposes (creating a malicious release in the original repo or exfiltrating repo secrets)? I understand you can limit the permissions of the token, but this is done within the workflow; the hacker can just as easily remove the limitations as part of the PR.
Is there any way to accomplish the three requirements without this security hole?
The must-read for this question is: Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests
GH Action provides the event type "pull_request_target", which has write permissions and can comment the PR. Do not use this without being careful! The PR's code is untrusted - if you build it, it might inject malicious code and compromise your repository and might steal your secrets.
The proposed solution for this is:
Have a workflow triggered by "pull_request" event. This runs with read-only GITHUB_TOKEN. Here you can run the unit tests. At the end of this workflow, the unit test results are uploaded as a build artifact.
Have another workflow, that is triggered by the event "workflow_run". It runs when the PR-workflow has completed. This second workflow runs in the context of the base repository with write-access GITHUB_TOKEN and all other configured secrets. It can download the artifact from the first workflow run and use this build result to create a comment to the PR.
Important: The incoming artifact data from the first workflow run must still be considered untrusted. But:
When used in a safe manner, like reading PR numbers or reading a code coverage text to comment on the PR, it is safe to use such untrusted data in the privileged workflow context.
See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for a complete usage example.
Note: Your screenshot about the configuration for "Fork pull request workflows" has meanwhile been renamed to "Fork pull request workflows in private repositories": With private repos, you are in control with whom you share your code. So you might decide to trust by default. But with public repository, anyone can fork the repo.
Update: All links to the github actions blog post series: