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-38361 — Aviso: CVE-2026-38361 múltiples vulnerabilidades DoS (CWE-400/CWE-670) en dash-uploader (Python/PyPI) | Kitploit
Herramientas/GitHubGitHub/a1ohadance/cve-2026-38361
Análisis de VulnerabilidadesExplotaciónSeguridad WebPruebas de PenetraciónAprendizaje y Educación
GitHuba1ohadance/cve-2026-38361

CVE-2026-38361

Aviso: CVE-2026-38361 múltiples vulnerabilidades DoS (CWE-400/CWE-670) en dash-uploader (Python/PyPI)

Ver Repositorio
hace 3 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-38361: Múltiples vulnerabilidades de DoS no autenticadas en dash-uploader

CVE NVD CWE-400 CWE-670 Severity Patch Auth Version PyPI Downloads Total Downloads License

Múltiples problemas de denegación de servicio (DoS) no autenticados en fohrloop/dash-uploader (Python, PyPI), incluidos, entre otros, la caída del proceso por agotamiento de memoria (OOM), la truncación de archivos a cero bytes, el agotamiento permanente del disco y la omisión completa del límite documentado de max_file_size. Existen vías adicionales de abuso de recursos a través del mismo conjunto de parámetros sin sanitizar.

⚠️ 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 (de 0.1.0 a 0.7.0a2) están afectadas y lo seguirán estando. El paquete sigue obteniendo aproximadamente 28 000 descargas mensuales.

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

Descripción

El manejador HTTP de dash-uploader acepta solicitudes POST no autenticadas con parámetros controlados por el atacante que se utilizan en la asignación de memoria, operaciones de archivo y creación de directorios sin comprobaciones de límites, sin límites de tasa y sin mecanismo de limpieza. Cuatro problemas independientes en la misma ruta de código:

1. Caída por OOM (verificada)

Verificado en un sistema de 7,7 GB: 5 solicitudes POST concurrentes con resumableTotalChunks=30000000 activaron el OOM killer de Linux en 2 segundos. El registro del kernel lo confirma:

root@kitploit:~
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB

Cada solicitud asigna aproximadamente 2,9 GB mediante una comprensión de lista sobre range(1, resumableTotalChunks + 1). El proceso del servidor se termina y la aplicación queda completamente indisponible hasta un reinicio manual.

2. Truncación de archivos (verificada)

Un archivo que contenía 42 bytes de datos se redujo a 0 bytes mediante una única solicitud POST con resumableTotalChunks=0. La causa raíz es que all() de Python devuelve True para iterables vacíos, lo que engaña al manejador de subida para que trate cero fragmentos como una subida completada. El archivo existente se elimina mediante os.unlink() y se reemplaza por un archivo vacío.

3. Acumulación de subidas abandonadas (verificada)

Se crearon 10 directorios temporales huérfanos con archivos de fragmentos que persistieron indefinidamente en el disco. Una búsqueda en toda la base de código en todos los archivos fuente de cleanup, ttl, expire, garbage, purge, cron, schedule y periodic arrojó cero resultados. La única llamada de limpieza (shutil.rmtree) se ejecuta exclusivamente en subidas completadas. No existe ningún mecanismo para recuperar espacio en disco de sesiones incompletas.

4. Omisión de max_file_size (verificada)

El servidor aceptó un fragmento de 5 MB para un archivo que declaraba resumableTotalSize=999999999999 (~999 GB) con HTTP 200. El parámetro max_file_size se pasa únicamente al componente JavaScript de React. El servidor nunca comprueba el tamaño del archivo, el tamaño del fragmento, Content-Length ni MAX_CONTENT_LENGTH de Flask. Un desarrollador que establezca max_file_size=10 no tiene protección en el lado del servidor.

Código vulnerable

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableTotalChunks = request.form.get("resumableTotalChunks", type=int)   # attacker-controlled, no bounds
    ...
    chunk_paths = [
        os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
        for x in range(1, resumableTotalChunks + 1)                              # unbounded; e.g. 30M -> ~2.9 GB -> OOM
    ]
    upload_complete = all([os.path.exists(p) for p in chunk_paths])              # all([]) is True -> truncation when chunks=0
    if upload_complete:
        target_file_name = os.path.join(temp_root, resumableFilename)
        if os.path.exists(target_file_name):
            os.unlink(target_file_name)                                          # existing file deleted
        with open(target_file_name, "ab") as target_file:
            for p in chunk_paths:                                                # empty list -> empty file written
                ...

La misma ruta de código produce tanto la caída por OOM (resumableTotalChunks grande) como la primitiva de truncación de archivos (resumableTotalChunks=0).

Vectores de ataque

Un atacante envía solicitudes POST no autenticadas al endpoint /API/resumable.

  • Caída por OOM: 5 solicitudes concurrentes con resumableTotalChunks=30000000 asignan ~2,9 GB cada una, activando el OOM killer.
  • Agotamiento del disco: iniciar subidas pero nunca completarlas; los archivos temporales huérfanos se acumulan para siempre.
  • Truncación de archivos: enviar resumableTotalChunks=0; Python all([])=True engaña al servidor para que sobrescriba el archivo objetivo con contenido vacío.
  • Omisión de tamaño: cualquier límite de tamaño establecido por el desarrollador se aplica solo en el JavaScript del cliente, por lo que una solicitud HTTP directa lo omite por completo.

No se requiere autenticación ni privilegios.

Impacto

  • Caída del proceso del servidor mediante el OOM killer de Linux provocada por la asignación de memoria sin límites a partir de un único parámetro POST controlado por el usuario (resumableTotalChunks)
  • Agotamiento permanente del disco a través de sesiones de subida abandonadas que nunca se limpian (no existe TTL, recolección de basura ni mecanismo de caducidad en la base de código)
  • Agotamiento de inodos del sistema de archivos mediante la creación de directorios de profundidad arbitraria a través de os.makedirs() con resumableIdentifier sin sanitizar
  • Destrucción de datos mediante la truncación de archivos a cero bytes causada por all() de Python que devuelve True para iterables vacíos cuando resumableTotalChunks=0
  • Omisión de todas las restricciones de tamaño de archivo porque max_file_size se aplica solo en el JavaScript del lado del cliente, mientras que el manejador del lado del servidor no realiza ninguna validación de tamaño y nunca establece MAX_CONTENT_LENGTH de Flask

Componentes afectados

  • dash_uploader/httprequesthandler.py (método BaseHttpRequestHandler._post)
  • dash_uploader/upload.py (función Upload, parámetro max_file_size)
  • dash_uploader/configure_upload.py (falta MAX_CONTENT_LENGTH)

Mitigación

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

Opciones para los usuarios con implementaciones actuales, en orden de preferencia:

  1. Migrar a dcc.Upload, el componente de subida oficial incluido con Plotly Dash. No tiene parámetro de número de fragmentos, no tiene estado temporal en disco y respeta MAX_CONTENT_LENGTH de Flask. Ninguno de los cuatro problemas aquí aplica. Es el más adecuado para archivos pequeños y medianos. Para subidas muy grandes, consulte el punto 2.
  2. Implementar un pequeño manejador de subidas en Flask con aplicación explícita del tamaño por solicitud (MAX_CONTENT_LENGTH), límites en cualquier recuento de fragmentos proporcionado por el cliente y una lista blanca de nombres de archivo aceptados.
  3. Si continúa usando dash-uploader, establezca MAX_CONTENT_LENGTH de Flask a nivel de aplicación (la biblioteca no lo hace) y rechace las entradas en la capa de aplicación o proxy inverso cuando se cumpla cualquiera de las siguientes condiciones:
    • resumableTotalChunks <= 0
    • resumableTotalChunks supere un límite razonable (p. ej., 10 000)
    • resumableTotalSize supere el max_file_size configurado por el desarrollador
  4. Agregue un límite de tasa en el endpoint de subida en la capa de proxy inverso o WAF para mitigar el vector de OOM por solicitudes concurrentes.
  5. Limpie periódicamente los directorios temporales huérfanos con un trabajo cron externo, ya que la biblioteca no tiene limpieza interna.

Cronología de divulgación

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 de 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-38361
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38361
  • https://github.com/fohrloop/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://libraries.io/pypi/dash-uploader
  • https://pepy.tech/project/dash-uploader
  • https://cwe.mitre.org/data/definitions/400.html
  • https://cwe.mitre.org/data/definitions/670.html
  • https://docs.python.org/3/library/functions.html#all

Descubridor

Muhammad Fitri Bin Mohd Sultan

Descargar herramienta
ID de CVECVE-2026-38361 (NVD)
VulnerabilidadConsumo de recursos no controlado (CWE-400), Implementación de flujo de control siempre incorrecta (CWE-670)
CVSS 3.17.5 / Alta (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Productodash-uploader
Versiones afectadasde 0.1.0 a 0.7.0a2 (las 18 versiones)
Versión corregidaninguna (proyecto archivado el 2025-07-19)
Vector de ataqueRemoto, no autenticado
DescubridorMuhammad Fitri Bin Mohd Sultan
Asignado porMITRE, 2026-05-07
RelacionadoCVE-2026-38360 (recorrido de rutas en la misma biblioteca)
FechaEvento
2026-03-19Vulnerabilidades descubiertas durante una investigación de seguridad en un despliegue de producción.
2026-03-22Solicitud de CVE enviada a MITRE.
2026-05-07CVE-2026-38361 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.