CVE-2026-58416

highPriorität · verfolgen · 0OT-Risiko · erhöhtEPSS 0.003 · 24. PerzentilDEEURUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.31% (24th) EPSS
CVSS 7.1 · high
Is it mine?
9 products
Prüfe deine Angriffsfläche
Who says so?
4 sources
enisa_euvd · fstec_bdu · osv · cert_bund

EPSS · bewertet 2026-10-27

Fork-PR Actions task can read a third private repository via the collaborative-owner branch (missing fork-PR guard)

01

cvss

Technischer Schweregrad, 0–10. Eine Zeile je Quelle.

7.1
010

Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen⚠ Quellen uneinig · medium–high · 6.3–7.1

v3.17.1highAV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:Nsecondary · FSTEC (BDU) RU
v3.17.1highCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:Nsecondary · ENISA EU
v3.17.1highCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:NsecondaryAusnutzbarkeit 1.8 · Auswirkung 4.7
v3.16.3mediumCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:Nsecondary · OSV
v3.16.5mediumCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N/E:Usecondary · CVSS-BT (t0sche)
02

SSVC

Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.

Trackcoordinatorcisa_ssvcUS
03

schwächen

Die CWE-Schwächeklassen, zu denen dies gehört.

04

betroffene Produkte (9)

Betroffene Produkte und Versionsbereiche.

05

Advisories (3)

Hersteller- und Ökosystem-Meldungen dazu.

  • WID-SEC-W-2026-2304Gitea: Mehrere SchwachstellenDeutsch2026-07-13csaf · cert_bundDE

    Ein Angreifer kann mehrere Schwachstellen in Gitea ausnutzen, um beliebigen Programmcode auszuführen, erweiterte Berechtigungen zu erlangen, Sicherheitsmaßnahmen zu umgehen, Daten zu manipulieren, sensible Informationen offenzulegen, Sitzungen zu übernehmen oder wiederzuverwenden oder einen Denial-of-Service-Zustand auszulösen.

  • GHSA-fj8v-hjwv-qm88Gitea: Fork-PR Actions task can read a third private repository via the collaborative-owner branch (missing fork-PR guard)2026-07-21ghsa · osvUS

    ### 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 ```go // 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: ```go 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 `GetActionsUserRepoPermission`, so it does not neutralize the gap — it just makes the leak read-only); secrets (`models/secret/secret.go`) and the approval gate (`services/actions/notifier_helper.go`) both correctly key on `IsForkPullRequest`. **Reachability** — the runner clones target repo B over git-HTTP with the task token: `routers/web/repo/githttp.go` → `GetDoerRepoPermission(ctx, repoB, ActionsUser)` → `GetActionsUserRepoPermission(ctx, repoB, actionsUser, taskID)` with `IsForkPullRequest == true` → collaborative-owner branch returns code-read → `p.CanAccess(Read, code)` passes → private clone of B succeeds. (`CheckRepoScopedToken` in githttp is a no-op for the Actions token.) ### PoC Setup: private base repo A (`usera/repoA`), private third repo B (`userb/repoB`) with a planted `SECRET.txt`, B's Actions config trusting `usera` as a collaborative owner, and a genuine running fork-PR task token (`token_hash` computed with Gitea's own `HashToken`) presented as HTTP Basic. Requesting `GET /userb/repoB.git/info/refs?service=git-upload-pack`: | Condition (same fork-PR token) | HTTP | Meaning | |---|---|---| | anonymous (no token) | 401 | auth required | | token, A **public**, B trusts A | 404 | branch gated on `taskRepo.IsPrivate` ⇒ A public skips it | | token, A private, B has **no** collab-owner config | 404 | no trust ⇒ denied | | **token, A private, B trusts A (collab-owner)** | **200** | **`git clone` of private B succeeds** | | config removed / restored | 404 / 200 | deterministic | In the 200 case, `git clone` of private repo B succeeded and yielded its `SECRET.txt` — the full source of a third private repo the fork-PR author has no rights to. ### Impact Read-only confidentiality breach: discloses the full source of a *third* private repository (B) to an untrusted external fork-PR author. Read-only, not write/RCE. Preconditions (honest): 1. B is deliberately configured with a collaborative owner — but that is exactly the feature's intended use, so realistic for any deployment using it. 2. The fork PR's base repo A is itself private (the branch is gated on `taskRepo.IsPrivate`). Forking a private A already requires read on A, so this is a normal internal-contributor situation, not a weakening — the escalation is "read A (granted) → read a *different* private repo B (never granted)." 3. The fork-PR workflow must actually run — most realistically via an attacker who had one earlier PR approved (the "approved before" path in `ifNeedApproval`), after which fork PRs auto-run. ### Suggested remediation Add the same fork-PR guard the sibling path has (one line): ```go if taskRepo.IsPrivate && !task.IsForkPullRequest { actionsUnit := repo.MustGetUnit(ctx, unit.TypeActions) if actionsUnit.ActionsConfig().IsCollaborativeOwner(taskRepo.OwnerID) { return maxPerm, nil } } ``` This flips `Vuln_ForkPR_LeaksThirdPrivateRepo` to PASS, keeps `Control_NonFork_Allowed` PASS (legitimate collaborative-owner sharing still works), and leaves the existing `TestGetActionsUserRepoPermission` suite all green.

  • GO-2026-6052Gitea: Fork-PR Actions task can read a third private repository via the collaborative-owner branch (missing fork-PR guard) in gitea.dev2026-07-22vendor · osvUS

    Gitea: Fork-PR Actions task can read a third private repository via the collaborative-owner branch (missing fork-PR guard) in gitea.dev

06

auch bekannt als (6)

Weitere Namen und Kennungen dieser Entität.

07

quellen

Welche Quellen diesen Datensatz belegen und wann.

veröffentlicht 2026-08-13geändert 2026-10-02
08

Referenzen (6)

Externe Belege — Patches, Meldungen, Analysen.

scry

Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.

Kostenloser Scan