GHSA-fj8v-hjwv-qm88: Gitea: Fork-PR Actions task can read a third private repository via the collaborative-owner branch (missing fork-PR guard)
Summary
GetActionsUserRepoPermission (models/perm/access/repo_permission.go) decides whether an Actions
task token may access a target repo. Its cross-repo branches each enforce a fork-PR discriminator —
except the collaborative-owner branch, which is missing the !task.IsForkPullRequest guard that
its sibling has. As a result, when a private repo B lists owner A as a collaborative owner, an
attacker-controlled fork pull-request workflow whose base repo is owned by A is granted code-read
on B — i.e. the fork's YAML can clone a third private repository it has no rights to.
Details
// models/perm/access/repo_permission.go (v1.26.2), in GetActionsUserRepoPermission
if checkSameOwnerCrossRepoAccess(ctx, taskRepo, repo, task.IsForkPullRequest) { // passes isForkPR -> denies forks
return maxPerm, nil
}
...
if taskRepo.IsPrivate { // <-- NO IsForkPullRequest check here
actionsUnit := repo.MustGetUnit(ctx, unit.TypeActions)
if actionsUnit.ActionsConfig().IsCollaborativeOwner(taskRepo.OwnerID) {
return maxPerm, nil // grants code-read to target repo B
}
}
The sibling same-owner path correctly denies fork PRs:
func checkSameOwnerCrossRepoAccess(ctx, taskRepo, targetRepo, isForkPR bool) bool {
if isForkPR {
return false // Fork PRs are never allowed cross-repo access to other private repositories.
}
...
}
taskRepo = the repo whose workflow is running (the PR's base repo A); repo = the target being
cloned (B). IsCollaborativeOwner(taskRepo.OwnerID) asks "does target B's Actions config trust A's
owner for cross-repo read?" When B trusts ownerA, the branch returns maxPerm (code-read) even when
task.IsForkPullRequest is true — i.e. when the executing YAML is the fork's, not A's.
Every sibling enforces the fork-PR discriminator; except for this branch:
checkSameOwnerCrossRepoAccess denies forks; ComputeTaskTokenPermissions
(models/actions/token_permissions.go) only clamps the token *ceiling* to read-only for fork/cross-repo
(its own comment notes the access *decision* is in G
Details
Original advisory: https://github.com/advisories/GHSA-fj8v-hjwv-qm88
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-58416 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
- high[NEW] [high] Gitea: Multiple vulnerabilitiescert-bund
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31