Gitea 的官方 Docker 镜像(最高至 1.26.2 及包括该版本)在其默认配置中包含了 REVERSE_PROXY_TRUSTED_PROXIES = *。如果你开启了反向代理登录,这个通配符意味着每个来源 IP 都被视为可信代理,因此任何能访问该端口的人都可以发送 X-WEBAUTH-USER 头部并以任意用户身份登录。无需密码,无需令牌。
我已将此问题报告给 Gitea,并在 1.26.3 / 1.26.4 中修复。本仓库是我自己的分析报告、一个可用的 PoC 以及一个检测工具。这是一个已修补的公开漏洞。
Gitea 支持反向代理认证:将其置于反向代理之后,代理设置 X-WEBAUTH-USER,Gitea 信任该头部作为用户名。只要只有你的代理能够设置它,这就是可行的。用于执行此限制的设置是 REVERSE_PROXY_TRUSTED_PROXIES,一个 IP 白名单。只有当请求的来源 IP 属于该白名单时,Gitea 才会认可该头部。
文档中安全的默认值(即 app.example.ini 中的值)是 127.0.0.0/8,::1/128:仅限回环地址,因此开箱即用仅信任本地代理。官方 Docker 镜像并未使用此默认值。它的 app.ini 模板硬编码了 *(docker/root/etc/templates/app.ini:55,以及 docker/rootless/etc/templates/app.ini:52 用于无根镜像)。* 匹配所有来源 IP,因此白名单检查无效。启用反向代理登录后,任何能访问该端口的人都可以发送该头部,而不仅仅是你的代理。如果开启了自动注册,账户会立即创建。发送管理员的用户名,你就成为了管理员。
因此,代码本身没有错误,问题出在打包的默认配置上,而且仅针对 Docker 镜像。遵循 app.example.ini 的二进制或自建安装会保留回环默认值,不受影响。
需要 Docker 和 Python 3(仅标准库,无需安装额外包)。
docker compose up -d # 启动存在漏洞的 gitea/gitea:1.26.2
# 等待约 30-60 秒完成首次启动设置,然后:
python3 poc.py # 随机新受害者,展示自动注册
python3 poc.py http://localhost:3000 admin # 冒充指定用户名
docker compose down -v # 清理环境
针对打包镜像的运行效果:
1) 不带头部访问 /user/settings -> HTTP 303 (重定向到登录页面 = 未认证)
2) 带 X-WEBAUTH-USER 头部访问 /user/settings -> HTTP 200
以 'pocadmin' 登录 - 无需密码、令牌,任意来源 IP
3) /pocadmin 用户资料页面 -> HTTP 200 (账户即时创建)
该绕过方式作用于 Web 会话,而非位于 /api/v1/... 的令牌 API,后者忽略该头部。
detect.py 发送一次无害探测,并与正常请求进行对比。它不会修改任何内容。
python3 detect.py https://gitea.example.com
它会输出 VULNERABLE(存在漏洞)、looks-safe(看起来安全)或 inconclusive(结论不明)。仅在你拥有或有权测试的实例上运行。
升级到 1.26.3 / 1.26.4 或更高版本。反向代理认证现在为可选启用,镜像不再附带通配符设置。如果你暂时无法升级,请将 REVERSE_PROXY_TRUSTED_PROXIES 设置为你代理的实际 IP 或 CIDR(绝不要使用 *),或者如果你不使用该功能,请关闭 ENABLE_REVERSE_PROXY_AUTHENTICATION。
我于 2026-05-26 发现此漏洞并向 Gitea 报告。我是 Gitea 安全公告(GHSA-f75j-4cw6-rmx4)中提到的报告者。
部分报道将此漏洞归功于 Exploitarium 仓库而非本人。这是错误的,并且与那个仓库发布的内容无关。此后我已联系多篇博客进行了更正;仍有少数几篇存在错误。
采用 MIT 许可证。详见 LICENSE。