Gitea
CVE-2026-50105
MEDIUM
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Feed endpoints are network-reachable via HTTP Basic token auth (PR:L); only metadata is disclosed, not file content, so C:L; no integrity or availability impact applies.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Lifecycle Timeline
2DescriptionGitHub Advisory
Summary
Gitea's RSS/Atom feed handlers accept API-token Basic auth but perform no token-scope or public-only enforcement. A personal access token that is correctly blocked (HTTP 403) from a private repository on /raw, /media, /archive, and /releases/download/... - because it is marked *public-only* or lacks the repository scope category - still returns that repository's private content through the feed routes. This is a token-confinement bypass and appears to be an incomplete fix of #37698, which added that scope enforcement to the download handlers but not to the sibling feed handlers.
This is not a cross-user access bug: the requesting account must still legitimately have repo read access (RepoAssignment + reqUnitCodeReader are enforced). What is bypassed is the guarantee that a *confined* token cannot reach private content - which is exactly the property #37698 was shipped to provide for downloads, and which matters when such a token is handed to a third-party service/CI, leaked, or used in a lower-trust integration.
Details
#37698 added context.CheckTokenScopes / CheckRepoScopedToken (services/context/permission.go) to the raw / media / archive / attachment download handlers, so a public-only or wrong-scope-category token cannot read private-repo content even when the owning user otherwise has access.
The feed handlers are registered with webAuth.AllowBasic (so they accept token Basic auth) but call no scope / public-only check. A grep for CheckTokenScopes / CheckRepoScopedToken / IsApiToken across routers/web/feed/ and the release feed handlers returns nothing.
Affected routes (all token-reachable via webAuth.AllowBasic, none call the scope check):
| Route | Handler | Private data exposed |
|---|---|---|
GET /{owner}/{repo}.rss / .atom | repo.Home → handleRepoHomeFeed (view_home.go) | last-10 commits: SHA, full message, author name + email |
GET /{owner}/{repo}/rss/branch/*, /atom/branch/* | feed.RenderBranchFeed* → ShowBranchFeed (routers/web/feed/branch.go) | same commit data, any branch |
GET /{owner}/{repo}/releases.rss / .atom | ReleasesFeedRSS/Atom (routers/web/repo/release.go) → ShowReleaseFeed | private release names, notes, descriptions |
GET /{owner}/{repo}/tags.rss / .atom | TagsListFeedRSS/Atom → ShowReleaseFeed | private tag names + messages |
GET /{user}.rss / .atom | showUserFeed (routers/web/feed/profile.go), `includePrivate = self \ | \ |
Inconsistency that pins this down: the branch-feed routes sit in the same route group as /raw, /media, /archive (all of which call checkDownloadTokenScope), and releases.rss sits next to /releases/attachments/{uuid} and /releases/download/... (both go through ServeAttachment → scope check). Only the feeds were missed. The API equivalents (ListReleases / ListTags) are scope-gated via tokenRequiresScopes.
Two distinct confinement bypasses:
- Public-only bypass. A token created with the *public-only* option is blocked (403) from a
private repo on /raw, /archive, /releases/download/..., but returns private commit / release data via .../releases.rss, .../rss/branch/*, /{owner}/{repo}.rss, and the owner's private activity via /{user}.rss.
- Scope-category bypass. A token scoped to only e.g.
read:issue(noread:repository) is
rejected by the download handlers but reads repository commit/release content via the feeds.
PoC
Verified live against the official gitea/gitea:1.26.2 Docker image (sqlite, feeds enabled).
Setup: non-admin user alice; private repo alice/secret with a commit "SECRET-COMMIT-MARKER ..." (file secret.txt) and a release "Private Release" / body "SECRET-RELEASE-MARKER ...". Two confined personal access tokens, both sent via HTTP Basic so the auth method is identical across download and feed - only the route differs:
- Token A: scopes
["public-only", "read:repository"] - Token B: scopes
["read:issue"]
# Token A - download is correctly blocked, feeds leak private content:
curl -u alice:$TOKEN_A https://<host>/alice/secret/raw/branch/main/secret.txt
# => 403 (fix works)
curl -u alice:$TOKEN_A https://<host>/alice/secret/rss/branch/main
# => 200, <title>SECRET-COMMIT-MARKER ...</title>
curl -u alice:$TOKEN_A https://<host>/alice/secret/releases.rss
# => 200, SECRET-RELEASE-MARKER ...
curl -u alice:$TOKEN_A "https://<host>/alice.rss"
# => 200, private activity
# Token B - wrong scope category, same split:
curl -u alice:$TOKEN_B https://<host>/alice/secret/raw/branch/main/secret.txt
# => 403
curl -u alice:$TOKEN_B https://<host>/alice/secret/rss/branch/main
# => 200, private commit leakedAnonymous baseline returns 404 on the repo feeds (data is genuinely private) and a marker-free 200 on /alice.rss (public activity only) - confirming the leak is gated only by the missing token check.
Impact
Information disclosure of private commit metadata (SHA, message, author name+email), release/tag notes, and the owner's private activity stream, to the holder of a confined token that was specifically configured *not* to reach private content. Not raw file blobs (feeds don't serve file contents). Requires a token belonging to an account that already has repo read access, so the realistic threat is a leaked / shared / lower-trust token rather than an anonymous attacker - which is precisely the threat model #37698 addressed for downloads.
Suggested remediation
Add a token-scope check at the top of each feed handler, mirroring checkDownloadTokenScope:
if context.CheckRepoScopedToken(ctx, ctx.Repo.Repository, auth_model.Read); ctx.Written() {
return
}for ShowBranchFeed, ShowRepoFeed, ShowFileFeed, ShowReleaseFeed (repo feeds). For the user feed, gate includePrivate behind a non-public-only token (or require the user / repository scope) so a confined token can't pull private activity.
AnalysisAI
RSS/Atom feed handlers in Gitea prior to v1.27.0 expose private repository content - commit metadata, release notes, tag names, and cross-repo activity streams - to holders of confined API tokens that are explicitly blocked from the same data via download routes. The bypass breaks the token-confinement guarantee introduced by PR #37698 for raw/archive/download handlers, which was never extended to the sibling feed endpoints despite those endpoints accepting identical token-based Basic auth. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | The attacker must hold a valid Gitea personal access token belonging to an account that already has repository read access (`RepoAssignment` and `reqUnitCodeReader` are enforced by the feed handlers). … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | The official CVSS 3.1 score of 4.3 (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N) accurately reflects the actual impact boundary: network-reachable with no special configuration required, but gated behind a valid authenticated token (PR:L) and limited to metadata-only confidentiality loss (C:L) - no raw file blobs are exposed. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | An attacker holds a Gitea personal access token scoped to `read:issue` only - deliberately restricted to block repository content access - belonging to a user who is a collaborator on a private repository. Substituting the feed URL `/alice/secret/rss/branch/main` in place of the blocked download URL `/alice/secret/raw/branch/main/secret.txt`, the attacker receives HTTP 200 with an Atom/RSS feed containing the last 10 commits' full messages, author names, and email addresses; a second request to `/alice/secret/releases.rss` reveals private release names and full release notes. … |
| Remediation | Upgrade to Gitea v1.27.0 or later, which resolves the confinement bypass per GHSA-6cqf-375w-639g (https://github.com/go-gitea/gitea/security/advisories/GHSA-6cqf-375w-639g) and the v1.27.0 release (https://github.com/go-gitea/gitea/releases/tag/v1.27.0). … Detailed patch versions, workarounds, and compensating controls in full report. |
Threat intelligence, references, and detailed analysis are available after sign-in.
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2
An issue in Plone Docker Official Image 5.2.13 (5221) open-source software that could allow for remote code execution du
Tandoor Recipes is an application for managing recipes, planning meals, and building shopping lists. Rated critical seve
Same weakness CWE-200 – Information Exposure
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-6cqf-375w-639g