rz1027/CVE-2026-20896

GitHub: rz1027/CVE-2026-20896

针对 Gitea Docker 镜像中反向代理认证通配符配置缺陷(CVE-2026-20896)的漏洞分析、PoC 和检测工具。

Stars: 6 | Forks: 0

# CVE-2026-20896 Gitea 官方 Docker 镜像(包括 1.26.2 及更早版本)在其 默认配置中内置了 `REVERSE_PROXY_TRUSTED_PROXIES = *`。如果你开启了反向代理登录, 该通配符意味着每个源 IP 都会被视为受信任的代理, 因此任何能够访问该端口的人都可以发送 `X-WEBAUTH-USER` header, 并以他们想要的任何身份登录。不需要密码,也不需要 token。 我已将此问题报告给 Gitea,并在 1.26.3 / 1.26.4 版本中修复。这个仓库是我自己的 分析文章、可用的 PoC 以及检测工具。这是针对一个已修复的公开漏洞。 - CVE 记录:https://www.cve.org/CVERecord?id=CVE-2026-20896(报告者:rz1027) - Gitea 安全公告:https://github.com/go-gitea/gitea/security/advisories/GHSA-f75j-4cw6-rmx4 - 修复 / 发布说明:https://blog.gitea.com/release-of-1.26.3-and-1.26.4/ ## 漏洞详情 Gitea 支持反向代理认证:你将它部署在一个设置了 `X-WEBAUTH-USER` 的代理后面,Gitea 就会信任该 header 中的用户名。只要 只有你的代理能设置它,这就没有问题。本应强制执行此操作的设置是 `REVERSE_PROXY_TRUSTED_PROXIES`,这是一个 IP 允许列表。Gitea 仅在请求的源 IP 在该列表内时, 才会处理该 header。 文档中安全的默认值,即 `app.example.ini` 中的值是 `127.0.0.0/8,::1/128`:仅限本地回环,因此开箱即用时仅信任本地代理。 官方 Docker 镜像并没有使用该设置。其 `app.ini` 模板 硬编码了 `*`(`docker/root/etc/templates/app.ini:55`,对于 rootless 镜像则是 `docker/rootless/etc/templates/app.ini:52`)。`*` 匹配 每个源 IP,因此允许列表检查形同虚设。开启反向代理登录后, 任何能够访问该端口的人都可以发送该 header,而不仅仅是你的代理。 如果开启了自动注册,账号会被立即创建。发送一个管理员的 用户名,你就会成为管理员。 所以代码本身没有错,问题出在打包的默认配置上,并且这是 Docker 镜像特有的。遵循 `app.example.ini` 的二进制文件或自行构建的安装版本保留了 本地回环的默认设置,因此不受影响。 ## 复现步骤 需要 Docker 和 Python 3(仅使用标准库,无需额外安装任何内容)。 ``` docker compose up -d # boots vulnerable gitea/gitea:1.26.2 # 给它 ~30-60s 完成首次运行设置,然后: python3 poc.py # random new victim, shows auto-registration python3 poc.py http://localhost:3000 admin # impersonate a chosen username docker compose down -v # clean up ``` 针对内置镜像运行的效果如下: ``` 1) /user/settings with no header -> HTTP 303 (redirect to login = not authed) 2) /user/settings with X-WEBAUTH-USER -> HTTP 200 logged in as 'pocadmin' - no password, no token, any source IP 3) /pocadmin profile page -> HTTP 200 (account created on the fly) ``` 如果没有该 header,页面会将你重定向到登录界面。而加上一个伪造的 header,同一个请求就会以该用户的身份认证通过返回。 (注意:这是一个 Web session 绕过。基于 token 的 `/api/v1/...` REST API 并不处理 `X-WEBAUTH-USER`。) ## 检查你自己的实例 `detect.py` 会发送一个无害的探测请求,并将其与正常请求进行比较。 它不会修改任何内容。 ``` python3 detect.py https://gitea.example.com ``` 如果实例登录了伪造的 header,它将输出 VULNERABLE(存在漏洞),否则会告诉你 它看起来是安全的。它输出的一个注意事项是:如果开启了反向代理认证但关闭了 自动注册,随机的探测名将无法登录,但现有用户的用户名仍然可能被冒用, 因此在这种情况下请检查你的配置。 请仅在你拥有或被允许测试的实例上运行此脚本。 ## 修复 升级到 1.26.3 / 1.26.4 或更高版本。反向代理认证现在默认是关闭的(opt-in),并且 镜像不再附带该通配符。如果你暂时无法升级,请将 `REVERSE_PROXY_TRUSTED_PROXIES` 设置为你的代理的实际 IP 或 CIDR(绝不能是 `*`),或者如果你不使用该功能,请关闭 `ENABLE_REVERSE_PROXY_AUTHENTICATION`。 ## 时间线 - 2026-05-26:私下报告给 Gitea。 - 2026-07-03:CVE-2026-20896 发布,归功于 rz1027。 - 在 Gitea 1.26.3 / 1.26.4 中修复。 ## 致谢 由 rz1027 (Ali Mustafa) 发现并报告。在 CVE 记录和 Gitea 1.26.3/1.26.4 发布说明中被列为报告者。 MIT 许可证。详见 [LICENSE](./LICENSE)。
标签:Docker安全, Gitea, PoC, 安全检测工具, 暴力破解, 漏洞分析, 版权保护, 请求拦截, 路径探测, 身份认证绕过, 逆向工具