-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update README regarding pull_request_target
#321
base: main
Are you sure you want to change the base?
Conversation
ref: refs/pull/${{ github.event.pull_request.number }}/head | ||
``` | ||
|
||
**WARNING! NEVER** run code from pull requests of public repositories! The token of `pull_request_target` event has write access. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matfax The pull_request_target
runs in the context of the base repository of the pull request, i.e., its GITHUB_TOKEN
has read/write access even for pull requests from forked repos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested various things now. Even though GITHUB_TOKEN doesn't seem to be available all the time, the github.token
from the context has indeed write permissions as you stated. actions/checkout sets this context token as repository token, so it's available anyways once checkout is used. I find it rather odd that GitHub introduced pull_request_target
as some kind of safe alternative but how are you supposed to check anything in a pull request if you can't even check out its code? Imho, they should change the permissions of the token if used in pull_request_target
to read only the repository + write access to the pull request (except merge). The use case of checking forked pull requests is integrated and documented insufficiently.
Is this a general warning or is this something specific to the checkout action? Github documentation isn't very clear about the token scope. It was my understanding that you'd need to pass down the token to your job. Is the real danger that this action persists the token during the whole job for git? Wouldn't this be safer if you just opt out of that behavior or are there other potential avenues to obtain the token? I guess any other action can just as well leak the token through the filesystem. |
@MinusFour It depends. Actions (such as
Next, there is the issue with the checkout token. Like many actions, checkout needs a token to evade API traffic restrictions. By default, this token will be stored during the whole workflow and deleted during its cleanup. Since git credentials are stored in the file system, that means a test could edit and push to the origin if this token has write permissions. I imagine it's even possible to force-push an empty git and lose the whole repository.
What's also integrated a bit prematurely, as it seems to me, is the token trigger behavior. The default GitHub token does and can not trigger any event. This was GitHub's decision to not see any loops where actions trigger themselves on and on. If a pull_request action does an auto fix and pushes it to the pull request with the default token, action checks won't be executed, and so it might seem as if all check pass after the fix. Thus, certain actions would require a git PAT to circumvent this. These PATs have greater access to the repositories, however. They don't expire after the workflow execution and could be stored somewhere for later access. And this isn't even the only use case where the default token doesn't work. Then, there are also actions that depend on it that the token doesn't trigger a repetitive execution. This security feature isn't supposed to be projected on the choice of default vs. PAT token. It should be a cross-cutting concern that can be enabled token-specifically just like any other scope. 💡 I think it would be best if they made default tokens read-only and offer an integrated way to generate step-wise tokens with individually-scoped access if any further access is required. A more granular scoping on repository-level wouldn't be bad either, e.g. to delimit a token scope to Until this happens, I'm currently working on an interactive event dispatcher action that requires maintainer approval for a check to run. This gives the maintainer the option to evaluate the pull request security-wise before any token is passed to it. |
This is for a private repository (personally, I think the
This is what worries me the most. As it is right now, a simple flow that checkout code, install dependencies and run tests could very easily reach secrets and whatnot. For example, the test suite could just run
I also believe this should be the default. It's essentially upgrading permissions for every step in the workflow that might not need them.
Unfortunately for repos that use self hosted runners and need to secure some of the runners, I think this would be a bad idea. Anyone could just change the In general I think it's a fair warning for both types of repositories, private or public. |
I think the bash:
output: This is a PR across forks which is a scenario the EDIT: Note sure if this was the best place to comment, but there could be another checkout option that could help checking out "the right thing" for PRs over forked repo's: https://github.community/t/github-actions-are-severely-limited-on-prs/18179/ |
@valentijnscholten Not being able to reach the base commit seems to be caused by |
I have tried all different kinds of combinations, including fetch depth 0.
But this checks out the original branch of the PR author. So this doesn't include the code that was added to the base branch later. When you try to checkout the merge commit to get the actual merge of the HEAD of the base branch and the HEAD of the PR, the result is that just the code from the base branch is checkout and none of the PR code is checked out.
So same results as
|
@valentijnscholten |
Thanks, will try. Just also found out that the below still gives errors because it can't find the base commit:
|
GitHub has introduced a new event type:
pull_request_target
, which allows to run workflows from base branch and pass a token with write permission.It could be potentially dangerous to checkout and run code from public forks, but people will still try it. I think the best place for the warning is the checkout action, itself.
Rendered