{"id":"CVE-2026-58440","aliases":["GHSA-66m4-5jjr-2rg5","GO-2026-6033"],"url":"https://o3.security/vulnerability/CVE-2026-58440","summary":"Webhooks created by a collaborator keep firing after their repo access is revoked → ongoing real-time exfiltration of private repo content (incomplete revocation cleanup in `DeleteCollaboration`)","details":"## Affected product\nGitea — `services/repository/collaboration.go` (`DeleteCollaboration`) + webhook delivery\n\n## Summary\nWhen a collaborator with admin permission on a private repo creates a webhook, that webhook keeps firing\nafter the collaborator's access is revoked. Gitea's revocation cleanup `DeleteCollaboration` removes the\ncollaboration record, recalculates accesses, drops watches, and unassigns issues — but it does **not**\nremove or disable webhooks the user created, and webhook delivery never re-checks whether the creator still\nhas repo access. The former collaborator therefore receives the full payload (issue/comment bodies, commit\ndata) of all future repository events at their controlled endpoint, indefinitely and invisibly.\n\n## Affected code\n- `services/repository/collaboration.go` → `DeleteCollaboration()` — cleans watches/assignees only; no\n  webhook cleanup.\n- Webhook delivery path — fires on repo events without re-validating the creator's current access.\n\n## Steps to reproduce\nUsing the provided reproduction materials:\n1. Attacker (admin collaborator) creates a webhook → revoke access.\n2. Control: `GET /api/v1/repos/admin/wh-repo` (attacker) → **404**.\n3. `GET .../hooks` → webhook still `active=true`.\n4. Admin creates a new issue **after** revocation → the catcher receives `action:\"opened\"`,\n   `issue.title:\"CRITICAL SECRET: …\"`, `issue.body` (sentinel private key), `repository.private:true`.\n(Runtime-confirmed on `gitea/gitea:1.25.4`. Catcher is an internal sentinel listener; the payload is a\nplanted sentinel, not real data; nothing is sent to any external/metadata endpoint.)\n\n## Impact\nAuthenticated former admin-collaborator → ongoing real-time exfiltration of private content created after\nrevocation; invisible to the owner; scope crosses from the application boundary to data the user should no\nlonger access.\n\n## Suggested remediation\n1. On revocation, delete/disable webhooks created by the removed collaborator (or hand them to the owner).\n2. Re-validate the creator's current repo access before each webhook delivery.\n3. At minimum, warn admins on revocation if the user created webhooks.\n\n## Credit\nReported as part of an incomplete-patch / authorization-residue measurement study (responsible disclosure).","published":"2026-08-13T16:44:54.496Z","modified":"2026-08-28T11:30:33.723242961Z","cvss":{"score":6.8,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N"},"epss":{"score":0.00278,"percentile":0.20354,"asOf":"2026-09-17"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"gitea.dev","fixedVersion":"1.27.0"}],"fix":{"url":"https://github.com/go-gitea/gitea/pull/38406","label":"go-gitea/gitea#38406"},"references":[{"type":"ADVISORY","url":"https://blog.gitea.com/gitea-1.27.0-is-released/"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/58xxx/CVE-2026-58440.json"},{"type":"ADVISORY","url":"https://github.com/go-gitea/gitea/releases/tag/v1.27.0"},{"type":"ADVISORY","url":"https://github.com/go-gitea/gitea/security/advisories/GHSA-66m4-5jjr-2rg5"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-58440"},{"type":"WEB","url":"https://github.com/go-gitea/gitea/pull/38406"},{"type":"WEB","url":"https://github.com/go-gitea/gitea/pull/38426"},{"type":"WEB","url":"https://github.com/go-gitea/gitea/commit/de4b8277e9cb576f2315fb03b5ab6478b42a1d31"},{"type":"WEB","url":"https://github.com/go-gitea/gitea/commit/f69e15afe7496cc62e96dab244629c69eb31a7bf"},{"type":"PACKAGE","url":"https://github.com/go-gitea/gitea"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-28T11:30:33.723242961Z"}}