Una plantilla de repo fue suficiente para RCE: lo que enseña el parche de Forgejo 16.0.4

Una plantilla de repo fue suficiente para RCE: lo que enseña el parche de Forgejo 16.0.4

Una plantilla de repo fue suficiente para RCE: lo que enseña el parche de Forgejo 16.0.4

La semana pasada salió Forgejo 16.0.4, y la mayoría de la gente lo pasó por alto porque es un release de esas notas largas de bugfixes de costumbre. Punto. Salvo que el primer ítem dice Crítico y explica algo que me dejó pensando un buen rato: una falla de ejecución remota de código que se aprovecha de la creación de repositorios a partir de plantillas. Si administras una instancia de Forgejo (o de Gitea, su pariente), pausa la lectura y actualiza ahora.

Cómo funciona el truco

El escenario es engañosamente simple. Forgejo permite crear un repositorio nuevo a partir de uno de plantilla. Internamente hace tres pasos: clona el repositorio plantilla, borra la carpeta .git para dejar los archivos limpios, y luego ejecuta la expansión de variables de plantilla sobre los archivos que están listados en .forgejo/template. Después de eso, inicializa un repositorio git nuevo.

El problema es el orden. La expansión de variables ocurre después de borrar el .git original, y podía usarse para recrear una carpeta .git maliciosa. Cuando Forgejo corría git init para el repositorio nuevo, git adoptaba esa carpeta como parte de la inicialización, y con eso un atacante podía leer datos arbitrarios del host de Forgejo y ejecutar procesos arbitrarios. Es decir, RCE completo.

Lo que más me gusta de este bug es lo pedagógico que es. No es un desbordamiento de buffer ni una cadena de cinco vulnerabilidades exóticas. Es un problema de orden de operaciones: entre «borrar lo viejo» y «crear lo nuevo» quedó una ventana donde un atacante metía su propio .git. El fix es igual de simple de entender: después de la expansión de plantilla, Forgejo elimina cualquier carpeta .git existente antes de inicializar el repositorio. Triar el directorio de nuevo en el momento correcto.

Por qué me importa aunque no use Forgejo

Yo administro un puñado de VPS con servicios self-hosted, y este tipo de falla me cala porque es exactamente la clase de bug que no aparece en los checklist de hardening. Nadie le pone ojo a la feature de «crear repo desde plantilla». Suena inofensiva, casi burocrática. Y sin embargo de ahí salió una vía para leer archivos del host: tokens, configs de base de datos, lo que tengas tirado en app.ini.

Otra lección: la misma release parchea un bug donde tokens de API con permisos restringidos podían escribir fuera de esos permisos al editar PRs, y una fuga donde cualquiera con acceso de lectura (incluso anónimos en repos públicos) podía descargar adjuntos de releases en borrador. Ese último es de la misma clase que Gitea arregló en CVE-2026-27660. Tres fallas de autorización distintas en una sola versión. Cuando un proyecto saca tres parches de seguridad de golpe, no es mala suerte: es señal de que conviene revisar tu versión con lupa.

Lo que haría yo hoy

Si tienes Forgejo o Gitea en producción: actualiza a 16.0.4 (o el backport correspondiente a tu rama) hoy, no el viernes. No esperes a tu ventana de mantenimiento mensual, porque el RCE no requiere credenciales en instancias donde cualquiera puede crear repositorios desde plantillas públicas. Revisa quién tiene permiso de crear repos en tu instancia, y si expones Forgejo a internet, mira los logs de creación de repositorios desde plantilla en las últimas semanas; es barato de hacer y te quita la duda.

Y una reflexión de cierre para quienes mantenemos cosas chiquitas: estos proyectos open source sacan parches correctos, con notas claras y CVEs documentados. La falla no es del software, es de nosotros que instalamos una vez y nos olvidamos. Un cron de una línea que revisa la versión contra el feed de releases te habría ahorrado esta semana de sudor frío. Cachai que es menos pega que restaurar un servidor comprometido.

Fuente de inspiración: Forgejo 16.0.4 release notes (critical RCE fix)

Comentarios

Aún no hay comentarios. ¿Por qué no comienzas el debate?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *