GHSA-QF2F-QH6P-7V89

Vulnerability from github – Published: 2026-07-21 20:13 – Updated: 2026-07-21 20:13
VLAI
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`
Details

Summary

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/starredgetStarredRepos() 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/timesListMyTrackedTimes() 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-test404. 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

  1. getStarredRepos: drop (or minimally redact) repos where permission.HasAnyUnitAccessOrPublicAccess() is false for the caller.
  2. ListMyTrackedTimes: filter tracked-time entries by current repo access.
  3. 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).

Show details on source website

{
  "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`"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

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.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…