
CVE-2026-52813 (Gogs Path Traversal → Git Hooks RCE) analyse défensive : analyse de la cause racine et du correctif, règles de détection Sigma/SIEM, IOCs, scanner de version non intrusif. Pas de PoC armé.
Recherche en sécurité / writeup orienté équipe bleue. Ce dépôt ne contient pas de PoC armé. Les chercheurs souhaitant reproduire doivent utiliser le PoC public référencé dans l'avis officiel.
| Projet | Contenu |
|---|---|
| CVE | CVE-2026-52813 |
| Alias | GHSA-c39w-43gm-34h5 / GO-2026-5305 |
| Versions affectées | Gogs < 0.14.3 |
| Version corrigée | 0.14.3 — PR #8334 |
| CVSS 3.1 | 10.0 Critique AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
| CWE | CWE-23 Traversée de chemin relatif → RCE |
| Prérequis | Un compte enregistré normal (inscription ouverte par défaut = RCE sans authentification) |
Lors de la création d'une organisation dans Gogs, le formulaire Web dispose d'une validation de caractères AlphaDashDot bloquant /, mais l'API REST POST /api/v1/user/orgs ne l'a pas. L'attaquant soumet via l'API un nom d'organisation contenant ../, contourne la validation et atteint directement os.MkdirAll(repoutil.UserPath(org.Name), 0777) (internal/database/org.go:165), ce qui écrit le répertoire du dépôt dans un chemin arbitraire du système de fichiers. Combiné avec l'arbre de travail temporaire de l'éditeur Web de Gogs (local-r/<repo_id>/), il est possible de déposer un hooks/update malveillant dans le checkout local d'un autre dépôt, exécuté automatiquement par git → RCE en tant qu'utilisateur git.
| Version de Gogs | Statut |
|---|---|
< 0.14.3 | Affecté, mettre à jour immédiatement |
>= 0.14.3 | Corrigé |
La mise à jour est la seule solution définitive :
# Docker
docker pull gogs/gogs:0.14.3
# Ou depuis les sources
git checkout v0.14.3 && go build
Atténuation temporaire (si mise à jour impossible) :
app.ini → [service] DISABLE_REGISTRATION = true), ce qui abaisse le prérequis de "sans authentification" à "compte existant requis" ;POST /api/v1/user/orgs, POST /api/v1/org/*/repos dont le corps JSON contient username / name avec .. ou / (voir detection/) ;/data/gogs/data/tmp/ (selinux/apparmor).Formulaire Web (internal/form/org.go, v0.14.2) :
type CreateOrg struct {
OrgName string `binding:"Required;AlphaDashDot;MaxSize(35)"` // regex ^[a-zA-Z0-9._-]+$
}
API (internal/route/api/v1/org/org.go, v0.14.2) :
// api.CreateOrgOption (go-gogs-client) étiquette de binding :
type CreateOrgOption struct {
UserName string `json:"username" binding:"Required"` // ← pas de AlphaDashDot !
}
→ Le champ username de POST /api/v1/user/orgs peut contenir n'importe quel caractère et atteint directement la couche base de données.
internal/database/users.go:1532 isNameAllowed ne bloque que les noms réservés/prefixes/suffixes (ex : admin, -bot), ne valide pas le jeu de caractères, donc ../ passe.
internal/repoutil/repoutil.go (v0.14.2) :
func UserPath(user string) string {
return filepath.Join(conf.Repository.Root, strings.ToLower(user)) // ← concaténation directe
}
internal/database/org.go:165 :
os.MkdirAll(repoutil.UserPath(org.Name), os.ModePerm) // org.Name contient ../ → écriture dans un chemin arbitraire
Lorsque Gogs traite les modifications de fichiers via Web/API, il extrait le dépôt dans /data/gogs/data/tmp/local-r/<repo_id>/. <repo_id> correspond exactement à l'id du dépôt dans la base de données. L'attaquant :
writer, obtient id == n ;username = "../../../../data/gogs/data/tmp/local-r/n/nested" → le répertoire physique tombe dans l'arbre de travail de writer ;rce-x → tombe dans local-r/n/nested/rce-x.git ;writer, place nested/rce-x.git/hooks/update comme fichier normal, le commit et le push (il se retrouve dans l'arbre de travail de writer) ;writer → Gogs exécute git dans local-r/n/ → git exécute hooks/update → RCE.Point clé : le hook malveillant est introduit comme contenu normal du dépôt via un push normal, aucune configuration
ENABLE_GIT_HOOKSn'est nécessaire — c'est la différence par rapport à la voie "abus de hooks git traditionnels".
Analyse détaillée du diff du correctif dans patch/ANALYSIS.md.
Règles complètes dans detection/ :
../) et l'exploitation réussie (écriture sur le système de fichiers)Les deux plus importantes :
POST /api/v1/user/orgs et POST /api/v1/org/*/repos avec username/name contenant .. ou / dans le corps JSON.nested/, rce-*.git, hooks/update) sous /data/gogs/data/tmp/local-r/*/.GET /api/v1/version si une instance Gogs est < 0.14.3, supporte le scan en masse, sortie CSV, adapté à l'inventaire des actifs.Ce dépôt ne fournit pas d'outil d'exploitation armé. Pour reproduire, utilisez le PoC public référencé dans l'avis officiel, et uniquement dans un environnement isolé auto-hébergé.
Les règles de detection/ doivent être validées sur un Gogs affecté. lab/docker-compose.yml fournit un environnement isolé Gogs 0.14.2 pour que l'équipe bleue teste si les règles de détection déclenchent. Ne pas exposer sur Internet, usage local uniquement.
| Date | Événement |
|---|---|
| 2026-06-08 | Réservation CVE |
| 2026-06-24 | Divulgation publique, publication de Gogs 0.14.3 |
| 2026-06-24 | Publication de l'avis officiel GHSA-c39w-43gm-34h5 |
Certains décrivent en ligne cette CVE comme "Exécution de code à distance par injection de paramètre gitrebase dans Gogs" — c'est faux. Cette vulnérabilité n'a rien à voir avec git rebase / gitrebase ; la cause racine est une traversée de chemin dans l'API. Ce document suit l'analyse réelle.
MIT — voir LICENSE.