
CVE-2026-52813 (Gogs Path Traversal → Git Hooks RCE) analisi difensiva: analisi della causa principale e della patch, regole di rilevamento Sigma/SIEM, IOC, scanner di versioni non intrusivo. Nessun PoC armato.
Ricerca sulla sicurezza / writeup orientato alla blue team. Questo repository non contiene PoC weaponizzati. I ricercatori che desiderano riprodurre il problema devono utilizzare il PoC pubblico citato nell'advisory ufficiale.
| Campo | Dettaglio |
|---|
| CVE | CVE-2026-52813 |
| Alias | GHSA-c39w-43gm-34h5 / GO-2026-5305 |
| Versioni interessate | Gogs < 0.14.3 |
| Versione corretta | 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 |
| Prerequisiti | Un normale account registrato (con registrazione aperta di default = RCE non autenticato) |
Quando Gogs crea un'organizzazione, il form Web applica la validazione dei caratteri AlphaDashDot che blocca /, ma la REST API POST /api/v1/user/orgs non lo fa. Un attaccante può inviare tramite API un nome di organizzazione contenente ../, aggirando la validazione e arrivando direttamente a os.MkdirAll(repoutil.UserPath(org.Name), 0777) (internal/database/org.go:165), scrivendo la directory del repository in un percorso arbitrario del file system. Combinando ciò con l'albero di lavoro temporaneo dell'editor Web di Gogs (local-r/<repo_id>/), è possibile collocare un hooks/update malevolo all'interno del checkout locale di un altro repository, che viene eseguito automaticamente da git → RCE con l'utente git.
| Versione Gogs | Stato |
|---|---|
< 0.14.3 | Interessata, aggiornare immediatamente |
>= 0.14.3 | Corretta |
L'aggiornamento è l'unica soluzione definitiva:
# Docker
docker pull gogs/gogs:0.14.3
# 或源码
git checkout v0.14.3 && go build
Mitigazioni temporanee (se non è possibile aggiornare):
app.ini → [service] DISABLE_REGISTRATION = true), riducendo il prerequisito da "non autenticato" ad "account già esistente";POST /api/v1/user/orgs e POST /api/v1/org/*/repos il cui corpo contenga .. o / nei campi username / name (vedi detection/);/data/gogs/data/tmp/ (selinux/apparmor).Form Web (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!
}
→ Il campo username di POST /api/v1/user/orgs può contenere caratteri arbitrari e arrivare direttamente al livello DB.
internal/database/users.go:1532 isNameAllowed blocca solo nomi riservati/prefissi/suffissi (es. admin, -bot), non valida il set di caratteri, quindi ../ passa.
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 含 ../ → 任意路径写入
Quando Gogs gestisce le modifiche ai file tramite Web/API, effettua il checkout del repository in /data/gogs/data/tmp/local-r/<repo_id>/. <repo_id> coincide esattamente con l'id del repository nel database. L'attaccante:
writer, ottenendo id == n;username = "../../../../data/gogs/data/tmp/local-r/n/nested" → la directory fisica finisce nell'albero di lavoro di writer;rce-x sotto quell'organizzazione → finisce in local-r/n/nested/rce-x.git;writer, committa e pusha nested/rce-x.git/hooks/update come file normale (finisce nell'albero di lavoro di writer);writer → Gogs esegue git in local-r/n/ → git esegue hooks/update → RCE.Punto chiave: la hook malevola entra tramite una normale push come contenuto ordinario del repository, senza bisogno della configurazione
ENABLE_GIT_HOOKS— questa è la differenza rispetto alla strada dell'"abuso tradizionale delle git hooks".
L'analisi dettagliata del diff della patch è in patch/ANALYSIS.md.
Le regole complete sono in detection/:
../) e lo sfruttamento riuscito (scrittura sul file system)Le due più importanti:
POST /api/v1/user/orgs e POST /api/v1/org/*/repos il cui corpo JSON contenga .. o / nei campi username/name./data/gogs/data/tmp/local-r/*/ (nested/, rce-*.git, hooks/update).GET /api/v1/version se un'istanza Gogs è < 0.14.3, supporta scansioni in batch e output CSV, adatto per l'inventario degli asset.Questo repository non fornisce strumenti di sfruttamento weaponizzati. Per la riproduzione, utilizzare il PoC pubblico citato nell'advisory ufficiale ed eseguirlo solo in un ambiente isolato allestito da voi.
Le regole in detection/ devono essere verificate su un Gogs vulnerabile; lab/docker-compose.yml fornisce un ambiente Gogs 0.14.2 isolato affinché la blue team possa testare se le regole di rilevamento scattano. Non esporlo a Internet, usarlo solo in locale.
| Data | Evento |
|---|---|
| 2026-06-08 | CVE riservato |
| 2026-06-24 | Divulgazione pubblica, rilascio di Gogs 0.14.3 |
| 2026-06-24 | Pubblicazione dell'advisory ufficiale GHSA-c39w-43gm-34h5 |
In rete c'è chi descrive questa CVE come "Gogs gitrebase parameter injection leading to remote code execution" — è sbagliato. Questa vulnerabilità non ha nulla a che fare con git rebase / gitrebase; la causa principale è il path traversal dell'API. Questo documento analizza la vulnerabilità reale.
MIT — vedi LICENSE.