Skip to content

Commit a84715e

Browse files
chmouelCursor
authored andcommitted
fix restrict same repo ACL perm to trusted context
Avoid granting issue_comment senders trust based solely on same-repo PR shape. Keep the same-repo fast path for pull_request events and PR rerequest flows, while forcing comment senders through collaborator, org-membership, or OWNERS checks. Add regression coverage to ensure issue_comment events do not bypass ACL and same-repo check_run/check_suite rerequests continue to work. Fixes #2664 Co-authored-by: Cursor <cursor@users.noreply.github.com> Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
1 parent 738cc02 commit a84715e

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

pkg/provider/github/acl.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,9 @@ func (v *Provider) aclCheckAll(ctx context.Context, rev *info.Event) (bool, erro
204204
return true, nil
205205
}
206206

207-
// If the user who has submitted the PR is not a owner or public member or Collaborator or not there in OWNERS file
208-
// but has permission to push to branches then allow the CI to be run.
209-
// This can only happen with GithubApp and Bots.
210-
// Ex: dependabot, bots
211-
if rev.PullRequestNumber != 0 {
207+
// Allow same-repo pull requests from bots or other non-members when the PR
208+
// branch lives in this repository instead of a fork.
209+
if v.canUseSameRepoPullRequestShortcut(rev) {
212210
isFromSameRepo := v.checkPullRequestForSameURL(ctx, rev)
213211
if isFromSameRepo {
214212
return true, nil
@@ -238,13 +236,30 @@ func (v *Provider) aclCheckAll(ctx context.Context, rev *info.Event) (bool, erro
238236
return v.IsAllowedOwnersFile(ctx, rev)
239237
}
240238

241-
// checkPullRequestForSameURL checks if a pull request's head and base branches are from the same repository.
242-
// means if the user has access to create a branch in the repository without forking or having any
243-
// permissions then PAC should allow to run CI.
239+
// canUseSameRepoPullRequestShortcut returns true only for event types where
240+
// the sender is expected to match the pull request author. That keeps the
241+
// same-repo shortcut available for PR and rerequest flows, but not comments.
242+
func (v *Provider) canUseSameRepoPullRequestShortcut(rev *info.Event) bool {
243+
if rev.PullRequestNumber == 0 {
244+
return false
245+
}
246+
247+
switch rev.Event.(type) {
248+
case *github.PullRequestEvent, *github.CheckRunEvent, *github.CheckSuiteEvent:
249+
return true
250+
default:
251+
return false
252+
}
253+
}
254+
255+
// checkPullRequestForSameURL returns true when the PR comes from another branch
256+
// in the same repository instead of from a fork.
244257
//
245-
// ex: dependabot, *[bot] etc...
258+
// This is the fast path that lets bot-authored PRs such as Dependabot run
259+
// without needing collaborator, org-member, or OWNERS access.
246260
//
247-
// HeadURL is set by getPullRequest() before aclCheckAll; if missing, fall through to other ACL checks.
261+
// HeadURL is filled by getPullRequest() before aclCheckAll. If it is missing,
262+
// ACL falls back to the regular membership checks.
248263
func (v *Provider) checkPullRequestForSameURL(_ context.Context, runevent *info.Event) bool {
249264
if runevent.HeadURL == "" {
250265
return false

pkg/provider/github/acl_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ func TestIfPullRequestIsForSameRepoWithoutFork(t *testing.T) {
708708
BaseURL: "http://org.com/owner/repo",
709709
HeadBranch: "main",
710710
BaseBranch: "dependabot",
711+
Event: &github.PullRequestEvent{},
711712
},
712713
pullRequestNumber: 1,
713714
allowed: true,
@@ -719,6 +720,7 @@ func TestIfPullRequestIsForSameRepoWithoutFork(t *testing.T) {
719720
Sender: "nonowner",
720721
Repository: "repo",
721722
PullRequestNumber: 1,
723+
Event: &github.PullRequestEvent{},
722724
},
723725
pullRequestNumber: 1,
724726
allowed: false,
@@ -734,10 +736,59 @@ func TestIfPullRequestIsForSameRepoWithoutFork(t *testing.T) {
734736
BaseURL: "http://org.com/owner/repo1",
735737
HeadBranch: "main",
736738
BaseBranch: "dependabot",
739+
Event: &github.PullRequestEvent{},
737740
},
738741
pullRequestNumber: 1,
739742
allowed: false,
740743
wantError: false,
744+
}, {
745+
name: "when issue comment sender is not trusted, same repo shortcut is not applied",
746+
event: &info.Event{
747+
Organization: "owner",
748+
Sender: "nonowner",
749+
Repository: "repo",
750+
PullRequestNumber: 1,
751+
HeadURL: "http://org.com/owner/repo",
752+
BaseURL: "http://org.com/owner/repo",
753+
HeadBranch: "main",
754+
BaseBranch: "dependabot",
755+
Event: &github.IssueCommentEvent{},
756+
},
757+
pullRequestNumber: 1,
758+
allowed: false,
759+
wantError: false,
760+
}, {
761+
name: "when check run rerequest resolves to same repo pull request the shortcut is applied",
762+
event: &info.Event{
763+
Organization: "owner",
764+
Sender: "dependabot[bot]",
765+
Repository: "repo",
766+
PullRequestNumber: 1,
767+
HeadURL: "http://org.com/owner/repo",
768+
BaseURL: "http://org.com/owner/repo",
769+
HeadBranch: "dependabot/npm-foo",
770+
BaseBranch: "main",
771+
Event: &github.CheckRunEvent{},
772+
},
773+
pullRequestNumber: 1,
774+
allowed: true,
775+
wantError: false,
776+
}, {
777+
name: "when check suite rerequest resolves to same repo pull request the shortcut is applied",
778+
event: &info.Event{
779+
Organization: "owner",
780+
Sender: "dependabot[bot]",
781+
Repository: "repo",
782+
PullRequestNumber: 1,
783+
HeadURL: "http://org.com/owner/repo",
784+
BaseURL: "http://org.com/owner/repo",
785+
HeadBranch: "dependabot/npm-foo",
786+
BaseBranch: "main",
787+
Event: &github.CheckSuiteEvent{},
788+
},
789+
pullRequestNumber: 1,
790+
allowed: true,
791+
wantError: false,
741792
},
742793
}
743794
for _, tt := range tests {

0 commit comments

Comments
 (0)