## https://sploitus.com/exploit?id=A80B7830-0196-594A-AA8C-1EF928459222
# CVE-2026-28699 โ Gitea OAuth2 Scope Bypass via HTTP Basic Auth
Self-contained lab + writeup for **CVE-2026-28699**: a Gitea OAuth2 access token scoped to only
`read:user` can perform full write actions just by being sent as
`Authorization: Basic base64(:x-oauth-basic)` instead of as a Bearer token. The OAuth2
scope system is bypassed for any token presented over Basic auth.
- **Affected:** ` Basic-auth write succeeds (scope bypassed)
python poc.py 1.26.2 # patched -> Basic-auth write blocked (403)
```
The single `poc.py` provisions a throwaway Gitea (SQLite, system temp dir), runs the **real**
OAuth2 authorization-code flow to mint a `read:user`-only token, then calls a write endpoint over
both Bearer and Basic and prints the verdict. Set `POC_DEBUG=1` to see the auth-flow steps.
### Expected output
Vulnerable `1.26.1`:
```
[Bearer] PATCH /api/v1/user/settings -> HTTP 403 (blocked)
[Basic ] PATCH /api/v1/user/settings -> HTTP 200 (ALLOWED -- scope BYPASSED)
>>> VULNERABLE: read:user token performed a write via Basic auth.
```
Patched `1.26.2`:
```
[Bearer] PATCH /api/v1/user/settings -> HTTP 403 (blocked)
[Basic ] PATCH /api/v1/user/settings -> HTTP 403 (blocked)
>>> PATCHED: scope enforced on both Bearer and Basic.
```
## Root cause in one table
| Auth presentation | `IsApiToken` | `ApiTokenScope` | scope enforced? |
|---|---|---|---|
| OAuth2 token via Bearer | `true` | set | โ yes |
| OAuth2 token via **Basic** | `true` | **missing** | โ **no (fails open)** |
| Personal access token | `true` | set | โ yes |
`services/auth/basic.go` set `IsApiToken` but not `ApiTokenScope` for OAuth2 tokens; the
`tokenRequiresScopes` middleware early-returns when the scope is absent. The 1.26.2 fix adds the
missing `store.GetData()["ApiTokenScope"] = accessTokenScope`.
## Files
| File | Purpose |
|---|---|
| [`WRITEUP.md`](WRITEUP.md) | Full root-cause analysis, impact, remediation, detection |
| `fetch_binaries.py` | Downloads the 1.26.1 / 1.26.2 binaries for your OS/arch |
| `poc.py` | Provisions Gitea, mints a `read:user` token, demonstrates Bearer-vs-Basic |
| `requirements.txt` | `requests` |
## โ ๏ธ Authorised use only
For education and authorised security testing (your own lab, CTF/HTB boxes, in-scope bug bounty
targets). The PoC stands up its own disposable Gitea โ point it at nothing you don't own.