Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-38360 — Aviso: CVE-2026-38360 recorrido de rutas (CWE-22) en dash-uploader (Python/PyPI) | Kitploit
Herramientas/GitHubGitHub/a1ohadance/cve-2026-38360
Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónSeguridad WebPruebas de PenetraciónAprendizaje y Educación
GitHuba1ohadance/cve-2026-38360

CVE-2026-38360

Aviso: CVE-2026-38360 recorrido de rutas (CWE-22) en dash-uploader (Python/PyPI)

Ver Repositorio
23hace 4 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-38360: Path Traversal en dash-uploader

CVE NVD CWE Severity Patch Auth Version PyPI Downloads

Total Downloads
License

Path traversal no autenticado en fohrloop/dash-uploader (Python, PyPI) que permite la escritura arbitraria de archivos, lo que conduce a (entre otros) ejecución remota de código (RCE), sobrescritura del código fuente de la aplicación, XSS almacenado e instalación de puertas traseras persistentes.

⚠️ No hay parche disponible y nunca se publicará ninguno

El repositorio fue archivado el 2025-07-19 sin un mantenedor activo. Todas las versiones publicadas (desde 0.1.0 hasta 0.7.0a2) están afectadas y seguirán estándolo. El paquete sigue registrando aproximadamente 28 000 descargas mensuales.

Cualquier persona que ejecute dash-uploader en producción debe aplicar una mitigación por su cuenta. La solución recomendada es migrar al componente dcc.Upload integrado de Plotly Dash. Consulta Mitigación para conocer todas las opciones.

ID de CVECVE-2026-38360 (NVD)
VulnerabilidadPath Traversal (CWE-22)
CVSS 3.19.8 / Crítico (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
Productodash-uploader
Versiones afectadas0.1.0 hasta 0.7.0a2 (las 18 versiones)
Versión corregidaninguna (proyecto archivado el 2025-07-19)
Vector de ataqueRemoto, sin autenticación
DescubridorMuhammad Fitri Bin Mohd Sultan
Asignado porMITRE, 2026-05-07
RelacionadoCVE-2026-38361 (DoS en la misma librería)

Descripción

Tres parámetros controlados por el usuario, obtenidos de request.form.get() en dash_uploader/httprequesthandler.py, se pasan directamente a os.path.join() y os.makedirs() sin ninguna sanitización ni validación:

  1. upload_id (línea 57 → línea 161, BaseHttpRequestHandler.get_temp_root): controla el directorio de destino. Un atacante puede enviar upload_id=../../../../usr/local/lib/python3.10/site-packages y los archivos se escribirán en el directorio de paquetes de Python.

  2. resumableFilename (línea 51 → línea 108, BaseHttpRequestHandler._post): controla el nombre de archivo final. Un atacante puede salir del directorio de carga mediante el nombre de archivo incluso con un upload_id legítimo.

  3. resumableIdentifier (línea 54 → línea 64, BaseHttpRequestHandler._post): se usa con os.makedirs() para crear el directorio temporal. Un atacante puede crear directorios arbitrarios en cualquier parte del sistema de archivos.

El endpoint de carga (/API/dash-uploader por defecto) no requiere autenticación. El hook http_request_handler añadido en v0.5.0 permite comprobaciones previas a la petición mediante post_before(), pero el método vulnerable _post() lee todos los parámetros directamente de request.form después de que el hook retorne. El hook no puede sanitizar los parámetros antes de que la librería los procese. Un desarrollador que añada autenticación mediante el hook seguirá siendo vulnerable al path traversal por parte de un usuario autenticado.

Código vulnerable

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableFilename = request.form.get("resumableFilename", default="error", type=str)
    resumableIdentifier = request.form.get("resumableIdentifier", default="error", type=str)
    upload_id = request.form.get("upload_id", default="", type=str)
    ...
    temp_root = self.get_temp_root(upload_id)                          # upload_id flows in here
    temp_dir = os.path.join(temp_root, resumableIdentifier)            # raw user input -> os.path.join
    if not os.path.isdir(temp_dir):
        os.makedirs(temp_dir)                                          # raw user input -> os.makedirs

def get_temp_root(self, upload_id):
    return os.path.join(self.upload_folder, upload_id)                 # no sanitization: ../../ escapes upload_folder

Tres sumideros de traversal independientes comparten la misma causa raíz: los valores del formulario llegan a os.path.join y os.makedirs sin validación.

Vectores de ataque

Un atacante remoto sin autenticar envía una petición HTTP POST multipart al endpoint de carga. Al inyectar secuencias de path traversal (../) en el parámetro de formulario upload_id, el atacante controla el directorio de destino del archivo subido. Por ejemplo, upload_id=../../../../usr/local/lib/python3.10/site-packages escribe archivos en el directorio de paquetes de Python, lo que permite RCE en el siguiente arranque del intérprete mediante la ejecución automática de .pth.

No se requiere autenticación, token de sesión ni token CSRF. Dos parámetros adicionales (resumableFilename y resumableIdentifier) proporcionan vectores de traversal independientes a través del mismo endpoint. La configuración predeterminada de la librería, tal como se muestra en la documentación oficial de inicio rápido, es explotable con un único comando curl.

Impacto

Escritura arbitraria de archivos en cualquier directorio escribible por el proceso del servidor. Esto se traduce en ejecución remota de código (RCE) mediante varias primitivas bien conocidas:

Primitivas de RCE

  • Depósito de un archivo .pth de Python en site-packages. Ejecuta código suministrado por el atacante en el siguiente arranque del intérprete.
  • Inyección de sitecustomize.py o usercustomize.py. Se ejecuta en cada inicio de Python.
  • Sobrescritura de un módulo de Python importable en el directorio de paquetes de la aplicación. Se ejecuta en la siguiente importación o reciclaje del worker.
  • Sobrescritura del punto de entrada WSGI/ASGI (p. ej., app.wsgi, wsgi.py). Se ejecuta en la siguiente recarga del worker.
  • Drop-in de cron (/etc/cron.d/, /etc/cron.hourly/, cola de crontab del usuario) cuando el proceso tiene los privilegios necesarios. Ejecución programada.
  • Drop-in de unidad systemd o unidad de usuario (/etc/systemd/system/, ~/.config/systemd/user/). Se ejecuta en el siguiente inicio del servicio o reinicio.
  • Inyección en /etc/ld.so.preload cuando el proceso se ejecuta como root. Precarga código del atacante en cada ejecución binaria posterior.
  • Sobrescritura de archivos de inicio del shell (~/.bashrc, ~/.profile, ~/.bash_profile). Se ejecuta en el siguiente inicio de sesión interactivo del usuario de la aplicación.
  • Añadido a ~/.ssh/authorized_keys. Otorga acceso SSH persistente al host como usuario de la aplicación.

Impacto a nivel web

  • Cross-site scripting almacenado en el dominio del host mediante la sobrescritura de JavaScript servido (por ejemplo, el JS del framework Dash en site-packages), que afecta a todos los usuarios en cada carga de página hasta que la aplicación se reinicie.
  • Sobrescritura del código fuente de la aplicación (una puerta trasera silenciosa y persistente que sobrevive a los despliegues normales cuando el mecanismo de despliegue no sobrescribe por completo las rutas afectadas).

Impacto en el sistema de archivos

  • Creación arbitraria de directorios en cualquier lugar al que el proceso pueda acceder, mediante os.makedirs() con el parámetro resumableIdentifier sin sanitizar (utilizable para el agotamiento de inodos o para preparar escrituras en árboles de directorios inexistentes).
  • Reemplazo de archivos entre usuarios en directorios de carga compartidos, lo que conduce al envenenamiento de datos entre inquilinos de la misma aplicación.

Componente afectado

  • dash_uploader/httprequesthandler.py
  • BaseHttpRequestHandler.get_temp_root()
  • BaseHttpRequestHandler._post()

Mitigación

⚠️ No hay parche disponible y el proyecto está archivado

Opciones para los usuarios que la tienen implementada actualmente, en orden de preferencia:

  1. Migrar a dcc.Upload, el componente de carga oficial incluido con Plotly Dash. Los archivos llegan al callback como una cadena base64; no se expone ningún handler que escriba en el sistema de archivos y no existe ninguna ruta de destino controlada por el cliente, por lo que esta clase de bug no aplica. Es la mejor opción para archivos pequeños y medianos. Para cargas muy grandes, consulta el punto 2.
  2. Implementar un pequeño handler de carga en Flask usando werkzeug.utils.secure_filename() y un directorio de destino fijo en el lado del servidor. Nunca aceptes valores de upload_id, nombre de archivo o identificador suministrados por el cliente como componentes de una ruta.
  3. Si se continúa usando dash-uploader, sitúa el endpoint de carga detrás de autenticación Y valida upload_id, resumableFilename y resumableIdentifier contra una lista de permitidos estricta (p. ej., solo UUID) en una capa que reescriba o rechace la petición antes de que el handler de la librería la vea. El hook http_request_handler de la librería NO previene el traversal porque los parámetros se leen de request.form después de que el hook retorne; la sanitización debe realizarse por encima de la librería.
  4. En la capa de proxy inverso o WAF, rechaza cualquier petición al endpoint de carga en la que cualquier campo del formulario contenga .., variantes codificadas (%2e%2e, ..%2f, %2e%2e%2f) o rutas absolutas.

Cronología de divulgación

FechaEvento
2026-03-17Vulnerabilidad descubierta durante una investigación de seguridad en una implementación de producción.
2026-03-19Solicitud de CVE enviada a MITRE.
2026-05-07CVE-2026-38360 asignado por MITRE.
2026-05-07Aviso público publicado.
2026-05-09Registro CVE publicado en la base de datos CVE de MITRE y en el NVD.

Contexto del paquete

  • Aproximadamente 28 000 descargas mensuales en PyPI (27 756 en los 30 días anteriores al 2026-05-07, con un volumen diario sostenido a pesar del archivado del repositorio). Fuente: pypistats.org.
  • Última versión publicada: 0.6.1 (línea estable). Las versiones preliminares llegan hasta 0.7.0a2.
  • Dependencia requerida: dash. Dependencia opcional: pyyaml. Licencia: MIT.
  • 11 paquetes dependientes, 6 repositorios dependientes.
  • 153 estrellas en GitHub.
  • Repositorio archivado el 2025-07-19 (Issue #153).
  • Sin CVEs previos (verificado contra NVD, GitHub Advisory Database, Snyk y OSV el 2026-03-19).

Referencias

  • https://www.cve.org/CVERecord?id=CVE-2026-38360
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38360
  • https://github.com/fohrloop/dash-uploader
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/blob/dev/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://cwe.mitre.org/data/definitions/22.html

Descubridor

Muhammad Fitri Bin Mohd Sultan

Descargar herramienta