
CVE-2026-52813 (Gogs Path Traversal → Git Hooks RCE) defensiver Writeup: Root-Cause- und Patch-Analyse, Sigma/SIEM-Erkennungsregeln, IOCs, nicht-intrusiver Versionsscanner. Kein weaponisiertes PoC.
Sicherheitsforschung / Blue-Team-Writeup. Dieses Repository enthält keinen weaponisierten PoC. Forscher, die eine Reproduktion benötigen, verwenden bitte den im offiziellen Advisory zitierten öffentlichen PoC.
| Projekt | Inhalt |
|---|---|
| CVE | CVE-2026-52813 |
| Aliasse | GHSA-c39w-43gm-34h5 / GO-2026-5305 |
| Betroffene Versionen | Gogs < 0.14.3 |
| Behobene Version | 0.14.3 — PR #8334 |
| CVSS 3.1 | 10.0 Critical AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
| CWE | CWE-23 Relative Path Traversal → RCE |
| Voraussetzungen | Ein normales registriertes Konto (bei standardmäßig offener Registrierung = nicht authentifizierte RCE) |
Gogs hat bei der Erstellung von Organisationen im Web-Formular eine AlphaDashDot-Zeichenvalidierung, die / blockiert, die REST-API POST /api/v1/user/orgs jedoch nicht. Angreifer übermitteln per API einen Organisationsnamen mit ../, umgehen die Validierung und gelangen direkt zu os.MkdirAll(repoutil.UserPath(org.Name), 0777) (internal/database/org.go:165), wodurch das Repository-Verzeichnis an einen beliebigen Dateisystempfad geschrieben wird. In Kombination mit dem temporären Arbeitsverzeichnis des Gogs-Web-Editors (local-r/<repo_id>/) kann ein bösartiges hooks/update innerhalb des lokalen Checkouts eines anderen Repositories abgelegt werden, das von git automatisch ausgeführt wird → RCE als Benutzer git.
| Gogs-Version | Status |
|---|---|
< 0.14.3 | Betroffen, sofort aktualisieren |
>= 0.14.3 | Behoben |
Ein Upgrade ist die einzige vollständige Behebung:
# Docker
docker pull gogs/gogs:0.14.3
# oder aus dem Quellcode
git checkout v0.14.3 && go build
Temporäre Eindämmung (falls kein Upgrade möglich ist):
app.ini → [service] DISABLE_REGISTRATION = true), wodurch die Voraussetzung von „nicht authentifiziert" auf „bestehendes Konto erforderlich" herabgestuft wird;POST /api/v1/user/orgs und POST /api/v1/org/*/repos blockieren, deren username- / name-Felder im Request-Body .. oder / enthalten (siehe detection/);/data/gogs/data/tmp/ hinaus einschränken (selinux/apparmor).Web-Formular (internal/form/org.go, v0.14.2):
type CreateOrg struct {
OrgName string `binding:"Required;AlphaDashDot;MaxSize(35)"` // 正则 ^[a-zA-Z0-9._-]+$
}
API (internal/route/api/v1/org/org.go, v0.14.2):
// api.CreateOrgOption (go-gogs-client) 的绑定 tag:
type CreateOrgOption struct {
UserName string `json:"username" binding:"Required"` // ← 没有 AlphaDashDot!
}
→ Das username-Feld von POST /api/v1/user/orgs kann beliebige Zeichen enthalten und erreicht direkt die DB-Schicht.
isNameAllowed in internal/database/users.go:1532 blockiert nur reservierte Namen/Präfix-Suffixe (z. B. admin, -bot), prüft den Zeichensatz nicht – daher wird ../ durchgelassen.
internal/repoutil/repoutil.go (v0.14.2):
func UserPath(user string) string {
return filepath.Join(conf.Repository.Root, strings.ToLower(user)) // ← 直接拼接
}
internal/database/org.go:165:
os.MkdirAll(repoutil.UserPath(org.Name), os.ModePerm) // org.Name 含 ../ → 任意路径写入
Wenn Gogs Web-/API-Dateibearbeitungen verarbeitet, checked es das Repository nach /data/gogs/data/tmp/local-r/<repo_id>/ aus. <repo_id> entspricht genau der Datenbank-id des Repositories. Ein Angreifer:
writer und erhält id == n;username = "../../../../data/gogs/data/tmp/local-r/n/nested" → das physische Verzeichnis landet im Arbeitsverzeichnis von writer;rce-x → landet unter local-r/n/nested/rce-x.git;writer, committet nested/rce-x.git/hooks/update als normale Datei und pusht sie (sie liegt dann im Arbeitsverzeichnis von writer);writer aus → Gogs führt git in local-r/n/ aus → git führt hooks/update aus → RCE.Kernpunkt: Der bösartige Hook gelangt als gewöhnlicher Repository-Inhalt über einen normalen Push hinein; die Konfiguration
ENABLE_GIT_HOOKSist nicht erforderlich – das unterscheidet dies vom „traditionellen Git-Hooks-Missbrauch".
Eine detaillierte Diff-Analyse des Patches findest du unter patch/ANALYSIS.md.
Vollständige Regeln unter detection/:
../) und erfolgreiche Ausnutzung (Ablage im Dateisystem) abDie zwei wichtigsten Punkte:
POST /api/v1/user/orgs und POST /api/v1/org/*/repos, wenn die Felder username/name im JSON-Body .. oder / enthalten./data/gogs/data/tmp/local-r/*/ (z. B. nested/, rce-*.git, hooks/update).GET /api/v1/version, ob eine Gogs-Instanz < 0.14.3 ist; unterstützt Batch-Scans und CSV-Ausgabe, geeignet für die Asset-Inventarisierung.Dieses Repository stellt keine weaponisierten Exploit-Tools bereit. Für die Reproduktion verwende bitte den im offiziellen Advisory zitierten öffentlichen PoC und führe sie nur in einer eigenen isolierten Umgebung durch.
Die Regeln in detection/ müssen gegen ein betroffenes Gogs validiert werden; lab/docker-compose.yml stellt eine isolierte Gogs-0.14.2-Umgebung bereit, damit das Blue Team testen kann, ob die Erkennungsregeln greifen. Nicht öffentlich erreichbar machen, nur lokal verwenden.
| Datum | Ereignis |
|---|---|
| 2026-06-08 | CVE reserviert |
| 2026-06-24 | Öffentliche Offenlegung, Gogs 0.14.3 veröffentlicht |
| 2026-06-24 | Offizielles Advisory GHSA-c39w-43gm-34h5 veröffentlicht |
Im Netz wird diese CVE teils als „Gogs gitrebase Parameterinjektion Remote Code Execution" beschrieben – das ist falsch. Diese Schwachstelle hat nichts mit git rebase / gitrebase zu tun; die Grundursache ist eine API-Pfadtraversierung. Dieses Dokument folgt der tatsächlichen Schwachstelle.
MIT — siehe LICENSE.