Gitea
CVE-2026-28699
HIGH
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Network API call (AV:N), no special conditions (AC:L), requires a valid OAuth2 token so PR:L, no user interaction post-consent; high C and I via profile/email/repo writes, no availability impact since deletion is scoped to the user's own repos.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Lifecycle Timeline
2DescriptionGitHub Advisory
Summary
Gitea fails to enforce OAuth2 access token scopes when the token is submitted via HTTP Basic authentication instead of a Bearer token. An OAuth2 application granted only read:user can use the same token as Authorization: Basic base64(<token>:x-oauth-basic) and perform write actions, including modifying profiles, adding email addresses, creating repositories, and deleting repositories as the authorizing user.
Details
Root cause: services/auth/basic.go accepts OAuth2 access tokens through the Basic auth path but does not store the token scope in the request context:
// services/auth/basic.go
if uid != 0 {
store.GetData()["LoginMethod"] = OAuth2TokenMethodName
store.GetData()["IsApiToken"] = true // scope is NOT set
return u, nil
}The scope enforcement middleware in routers/api/v1/api.go exits early when ApiTokenScope is absent:
// routers/api/v1/api.go - tokenRequiresScopes
scope, scopeExists := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope)
if ctx.Data["IsApiToken"] != true || !scopeExists {
return //<- exits without checking scope, all actions permitted
}When a token arrives via Bearer, ApiTokenScope is populated and scope checks apply normally. When the same token arrives via Basic auth, ApiTokenScope is never set, so tokenRequiresScopes returns immediately and no scope is enforced.
Suggested fix: When an OAuth2 access token is accepted in services/auth/basic.go, populate ApiTokenScope in the request context identically to the Bearer-token OAuth2 path.
PoC
- Create an OAuth2 application in Gitea.
- Authorize it as a normal user with scope
read:useronly. - Take the resulting access token and call a write endpoint both ways:
Bearer | correctly blocked:
Authorization: Bearer <token>
PATCH /api/v1/user/settings -> 403 ForbiddenBasic | bypass:
Authorization: Basic base64(<token>:x-oauth-basic)
PATCH /api/v1/user/settings -> 200 OKAll verified bypass endpoints using a read:user-only token:
| Endpoint | Bearer | Basic |
|---|---|---|
PATCH /api/v1/user/settings | 403 | 200 |
POST /api/v1/user/emails | 403 | 200 |
POST /api/v1/user/repos | 403 | 200 |
PATCH /api/v1/repos/{owner}/{repo} | 403 | 200 |
DELETE /api/v1/repos/{owner}/{repo} | 403 | 200 |
The bypass respects the user's normal repository permissions, it does not grant access to repositories the user cannot otherwise reach, and does not escalate to admin.
Impact
Any OAuth2 application with any restricted scope can silently operate beyond its granted permissions by switching from Bearer to Basic auth. An attacker who obtains a token (e.g. via a malicious OAuth2 app a user authorized) can:
- Modify the victim's profile and settings
- Add attacker-controlled email addresses to the victim's account
- Create repositories as the victim
- Modify or delete the victim's private repositories
The entire OAuth2 scope system is effectively bypassed for any token submitted via Basic auth.
AnalysisAI
OAuth2 scope enforcement bypass in Gitea <= 1.26.1 allows any OAuth2 access token to perform write actions far beyond its granted scope when submitted via HTTP Basic authentication instead of as a Bearer token. A token issued with only read:user can modify user settings, add attacker-controlled emails, and create or delete the user's repositories, effectively nullifying the entire OAuth2 scope model for Basic-auth requests. …
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 | Requires the Gitea instance to have the OAuth2 provider feature enabled and at least one OAuth2 application registered and authorized by a target user, yielding a valid OAuth2 access token that the attacker controls (e.g., via operating a malicious OAuth2 app, phishing the authorization flow, or stealing an existing token). … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | The CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N, 8.1 High) accurately reflects a network-reachable, low-complexity bypass requiring an existing OAuth2 token (PR:L) with high confidentiality and integrity impact but no availability impact - the attacker cannot exceed the authorizing user's underlying permissions, so blast radius is bounded by that user's account and repositories. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | A user installs or authorizes a seemingly benign third-party OAuth2 application against the organization's Gitea instance, granting only `read:user` scope. The malicious application takes the issued access token, re-sends it as `Authorization: Basic base64(<token>:x-oauth-basic)` to `/api/v1/user/emails`, adds an attacker-controlled email, and then triggers a password reset to that address - or calls `DELETE /api/v1/repos/{owner}/{repo}` to destroy the victim's private repositories. … |
| Remediation | Vendor-released patch: upgrade Gitea to 1.26.2 or later, as published in GHSA-9r5x-wg6m-x2rc (https://github.com/go-gitea/gitea/security/advisories/GHSA-9r5x-wg6m-x2rc). … Detailed patch versions, workarounds, and compensating controls in full report. |
Recommended ActionAI
Within 24 hours: Audit all OAuth2 tokens in use in your Gitea deployment, document tokens with read-only or limited scopes, review access logs for suspicious write operations with low-privilege tokens, and disable HTTP Basic authentication for OAuth2 submissions if operationally feasible. …
Sign in for detailed remediation steps and compensating controls.
Threat intelligence, references, and detailed analysis are available after sign-in.
More from same product – last 7 days
Stored cross-site scripting in Gitea 1.25.x affects the built-in 3D file viewer (Online3DViewer integration) where a cra
Authorization bypass in Gitea versions up to and including 1.26.1 allows any authenticated user with mere read access to
Authorization scope bypass in Gitea v1.26.1 and earlier allows authenticated users to use OAuth2/PAT Bearer tokens to pe
Authorization bypass in Gitea versions 1.22.3 through 1.26.1 allows holders of `public-only` access tokens or OAuth gran
Authorization bypass in Gitea versions prior to 1.26.0 lets a read-only organization member create repositories in the o
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-9r5x-wg6m-x2rc