GHSA-QF2F-QH6P-7V89
Vulnerability from github – Published: 2026-07-21 20:13 – Updated: 2026-07-21 20:13Summary
CVE-2026-20800 fixed private-info leakage to revoked users only for the notification endpoint. Two
sibling endpoints that return data keyed on the caller's own relationship still do not re-check repo
access at output time:
- GET /api/v1/user/starred — getStarredRepos() computes a per-repo permission but still lists every
starred repo (no filtering), so the full repo object (full_name, private, clone_url, ssh_url)
of a now-inaccessible private repo is returned.
- GET /api/v1/user/times — ListMyTrackedTimes() queries by UserID only and LoadAttributes brings
in the issue (title, state), leaking private issue titles after revocation.
Steps to reproduce
Using the provided reproduction materials, as a revoked user:
1. Control: GET /api/v1/repos/admin/starred-test → 404.
2. GET /api/v1/user/starred → leaks admin/starred-test, private:true, clone_url.
3. GET /api/v1/user/times → leaks issue.title = "SECRET: …", state.
(Runtime-confirmed on gitea/gitea:1.25.4. Oracle = planted sentinel title; no real secret exfiltrated.)
Impact
A former collaborator can enumerate private repos they starred and read private issue titles they logged time on, indefinitely after access revocation. Metadata only (no repo content / comment bodies). Low.
Suggested remediation
getStarredRepos: drop (or minimally redact) repos wherepermission.HasAnyUnitAccessOrPublicAccess()is false for the caller.ListMyTrackedTimes: filter tracked-time entries by current repo access.- Optionally clear a user's stars / time entries for a private repo on revocation.
Credit
Reported as part of an incomplete-patch measurement study (responsible disclosure).
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "code.gitea.io/gitea"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.27.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-59766"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-21T20:13:03Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\nCVE-2026-20800 fixed private-info leakage to revoked users only for the notification endpoint. Two\nsibling endpoints that return data keyed on the caller\u0027s own relationship still do not re-check repo\naccess at output time:\n- `GET /api/v1/user/starred` \u2014 `getStarredRepos()` computes a per-repo permission but still lists every\n starred repo (no filtering), so the full repo object (`full_name`, `private`, `clone_url`, `ssh_url`)\n of a now-inaccessible private repo is returned.\n- `GET /api/v1/user/times` \u2014 `ListMyTrackedTimes()` queries by `UserID` only and `LoadAttributes` brings\n in the issue (`title`, `state`), leaking private issue titles after revocation.\n\n## Steps to reproduce\nUsing the provided reproduction materials, as a revoked user:\n1. Control: `GET /api/v1/repos/admin/starred-test` \u2192 **404**.\n2. `GET /api/v1/user/starred` \u2192 leaks `admin/starred-test`, `private:true`, `clone_url`.\n3. `GET /api/v1/user/times` \u2192 leaks `issue.title = \"SECRET: \u2026\"`, `state`.\n\n(Runtime-confirmed on `gitea/gitea:1.25.4`. Oracle = planted sentinel title; no real secret exfiltrated.)\n\n## Impact\nA former collaborator can enumerate private repos they starred and read private issue titles they logged\ntime on, indefinitely after access revocation. Metadata only (no repo content / comment bodies). Low.\n\n## Suggested remediation\n1. `getStarredRepos`: drop (or minimally redact) repos where `permission.HasAnyUnitAccessOrPublicAccess()`\n is false for the caller.\n2. `ListMyTrackedTimes`: filter tracked-time entries by current repo access.\n3. Optionally clear a user\u0027s stars / time entries for a private repo on revocation.\n\n## Credit\nReported as part of an incomplete-patch measurement study (responsible disclosure).",
"id": "GHSA-qf2f-qh6p-7v89",
"modified": "2026-07-21T20:13:03Z",
"published": "2026-07-21T20:13:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/go-gitea/gitea/security/advisories/GHSA-qf2f-qh6p-7v89"
},
{
"type": "PACKAGE",
"url": "https://github.com/go-gitea/gitea"
},
{
"type": "WEB",
"url": "https://github.com/go-gitea/gitea/releases/tag/v1.27.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Gitea CVE-2026-20800 sibling endpoints not covered: revoked user still reads private repo objects via `/api/v1/user/starred` and private issue titles via `/api/v1/user/times`"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.