
CVE-2026-52813 (Gogs Path Traversal → Git Hooks RCE) informe defensivo: análisis de causa raíz y del parche, reglas de detección Sigma/SIEM, IOCs, escáner de versiones no intrusivo. Sin PoC armado.
Investigación de seguridad / writeup para equipo azul. Este repositorio no contiene ningún PoC weaponizado. Los investigadores que necesiten reproducir el fallo deben usar el PoC público referenciado en el advisory oficial.
| Campo | Contenido |
|---|---|
| CVE | CVE-2026-52813 |
| Alias | GHSA-c39w-43gm-34h5 / GO-2026-5305 |
| Versiones afectadas | Gogs < 0.14.3 |
| Versión corregida | 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 |
| Requisito previo | Una cuenta registrada normal (con el registro abierto por defecto = RCE sin autenticación) |
Al crear una organización, Gogs aplica la validación de caracteres AlphaDashDot en el formulario web para bloquear /, pero la API REST POST /api/v1/user/orgs no la aplica. El atacante envía un nombre de organización con ../ a través de la API, evade la validación y llega directamente a os.MkdirAll(repoutil.UserPath(org.Name), 0777) (internal/database/org.go:165), escribiendo el directorio del repositorio en cualquier ruta del sistema de archivos. Combinado con el árbol de trabajo temporal del editor web de Gogs (local-r/<repo_id>/), puede desplegar un hooks/update malicioso dentro del checkout local de otro repositorio, que git ejecuta automáticamente → RCE como el usuario git.
| Versión de Gogs | Estado |
|---|---|
< 0.14.3 | Afectada, actualice de inmediato |
>= 0.14.3 | Corregida |
La actualización es la única medida de corrección definitiva:
# Docker
docker pull gogs/gogs:0.14.3
# 或源码
git checkout v0.14.3 && go build
Mitigaciones temporales (cuando no se puede actualizar):
app.ini → [service] DISABLE_REGISTRATION = true), degradando el requisito previo de "sin autenticación" a "requiere una cuenta existente";POST /api/v1/user/orgs y POST /api/v1/org/*/repos cuyo cuerpo contenga .. o / en los campos username / name (ver detection/);/data/gogs/data/tmp/ (selinux/apparmor).Formulario 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!
}
→ El campo username de POST /api/v1/user/orgs puede contener cualquier carácter y llegar directamente a la capa de base de datos.
internal/database/users.go:1532 isNameAllowed solo bloquea nombres reservados y prefijos/sufijos (como admin, -bot), no valida el juego de caracteres, por lo que ../ puede pasar.
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 含 ../ → 任意路径写入
Cuando Gogs procesa la edición de archivos vía Web/API, hace checkout del repositorio en /data/gogs/data/tmp/local-r/<repo_id>/. <repo_id> coincide exactamente con el id del repositorio en la base de datos. El atacante:
writer y obtiene id == n;username = "../../../../data/gogs/data/tmp/local-r/n/nested" → el directorio físico queda dentro del árbol de trabajo de writer;rce-x dentro de esa organización → queda en local-r/n/nested/rce-x.git;writer, hace commit de nested/rce-x.git/hooks/update como archivo normal y hace push (queda dentro del árbol de trabajo de writer);writer → Gogs ejecuta git en local-r/n/ → git ejecuta hooks/update → RCE.Punto clave: el hook malicioso entra como contenido normal del repositorio mediante un push legítimo y no requiere la configuración
ENABLE_GIT_HOOKS— esa es la diferencia con la vía del "abuso tradicional de git hooks".
El análisis detallado del diff del parche está en patch/ANALYSIS.md.
Reglas completas en detection/:
../) y la explotación exitosa (despliegue en el sistema de archivos)Las dos más críticas:
POST /api/v1/user/orgs y POST /api/v1/org/*/repos cuyo cuerpo JSON contenga .. o / en los campos username/name.nested/, rce-*.git, hooks/update) bajo /data/gogs/data/tmp/local-r/*/.GET /api/v1/version si la instancia de Gogs es < 0.14.3; admite escaneo masivo y salida CSV, ideal para el inventario de activos.Este repositorio no proporciona herramientas de explotación weaponizadas. Para reproducir el fallo, use el PoC público referenciado en el advisory oficial y hágalo únicamente en un entorno aislado propio.
Las reglas de detection/ deben validarse en una instancia de Gogs afectada; lab/docker-compose.yml proporciona un entorno aislado de Gogs 0.14.2 para que el equipo azul pruebe si las reglas de detección aciertan. No lo exponga a Internet; úselo solo localmente.
| Fecha | Evento |
|---|---|
| 2026-06-08 | CVE reservado |
| 2026-06-24 | Divulgación pública; lanzamiento de Gogs 0.14.3 |
| 2026-06-24 | Publicación del advisory oficial GHSA-c39w-43gm-34h5 |
Hay quien describe este CVE como "inyección de parámetros gitrebase con ejecución remota de código en Gogs" — es incorrecto. Esta vulnerabilidad no tiene relación con git rebase / gitrebase; la causa raíz es un path traversal en la API. Este documento sigue el análisis real de la vulnerabilidad.
MIT — ver LICENSE.