Archivos de prueba de casos límite: corruptos, truncados, vacíos y mal etiquetados

36 archivos · enlaces directos · sin anuncios · uso libre

Sin bombas ZIPSin ejecutablesSin cadenas de malwareSHA-256 publicadoSeguro de extraer

El resto de esta biblioteca responde a "dame un PNG válido". Esta página responde a la pregunta difícil: ¿qué hace tu código con un archivo truncado, vacío, mal nombrado, que miente sobre su tipo o que trae datos que no debería? Esas son las subidas que llegan a producción, y construirlas a mano es tan tedioso que la mayoría de las suites de pruebas nunca las prueban.

Todos los archivos de aquí son seguros. No hay bombas zip, ni entradas con path traversal, ni ejecutables, ni cadenas de prueba de malware; el archivo comprimido más grande se descomprime en menos de un megabyte. Los fallos son reales, las cargas útiles no son peligrosas, y se publica el SHA-256 de cada archivo para que puedas fijarlo como fixture.

Empieza por dos. El archivo HTML con extensión .jpg te dice si una subida de imagen puede convertirse en un cross-site scripting almacenado en tu dominio. El CSV con fórmulas te dice si tus exportaciones llegan a la hoja de cálculo de un compañero como fórmulas activas. Son los dos que más fallos reales encuentran.

Archivos vacíos y casi vacíos

Una subida de cero bytes es lo que más a menudo se olvida. Los validadores que comprueban un tamaño máximo suelen olvidar el mínimo, y el código que lee el primer byte antes de comprobar la longitud falla aquí en lugar de devolver un error limpio.

ArchivoQué pruebaTamañoDescargar
zero-byte.txtCompletamente vacío. Prueba la validación de tamaño mínimo, las divisiones por la longitud y el código que lee un primer byte sin comprobar antes que exista.0 BDescargar
one-byte.txtUn solo carácter. Es demasiado pequeño para contener una cabecera válida de cualquier formato, así que la detección del tipo debe fallar de forma controlada.1 BDescargar
empty-archive.zipUn ZIP estructuralmente válido sin ninguna entrada. La extracción debe completarse sin producir nada, no lanzar una excepción.22 BDescargar

Archivos truncados y dañados

Tienen una cabecera válida y datos incompletos o dañados, que es justo el aspecto de una subida interrumpida. El código que se fía de la cabecera y procesa el resto fallará aquí, y el punto donde falle te dirá si tu gestión de errores está donde crees.

ArchivoQué pruebaTamañoDescargar
truncated.pngFirma PNG e IHDR válidas, cortado a mitad de los datos de imagen. Los decodificadores lanzan un error en lugar de devolver una imagen parcial.4 KBDescargar
corrupt-crc.pngLongitud completa y estructura correcta, pero se ha invertido un byte dentro de los datos de imagen y el CRC almacenado ya no coincide. Los decodificadores estrictos lo rechazan; los permisivos devuelven píxeles incorrectos.9 KBDescargar
truncated.jpgUn JPEG cortado al 60 por ciento, sin marcador de fin de imagen. Muchos decodificadores devuelven una imagen decodificada en parte en lugar de fallar, y conviene saber qué hace el tuyo.603 BDescargar
truncated.zipEl directorio central está cortado, que es justo el aspecto de un archivo comprimido subido a medias. Es el ZIP dañado más habitual en la práctica.3 KBDescargar
malformed.jsonUna coma final, una clave sin comillas y una llave sin cerrar. Comprueba que tu analizador indica una posición útil en lugar de un error genérico.136 BDescargar

Archivos que mienten sobre su tipo

La extensión dice una cosa y los bytes, otra. Si tu gestor de subidas se fía de la extensión o del Content-Type que envía el navegador, estos archivos pasan. El que importa es el archivo HTML con nombre .jpg: si se sirve con un tipo de contenido de imagen es inofensivo, pero si se sirve como HTML desde tu dominio es un cross-site scripting almacenado.

ArchivoQué pruebaTamañoDescargar
actually-a-png.jpgUn PNG auténtico con extensión .jpg. Todo lo que decida según la extensión se lo pasará al decodificador equivocado.9 KBDescargar
actually-html.jpgUn documento HTML con extensión .jpg. Si tu aplicación lo guarda y lo vuelve a servir con un tipo de contenido adivinado, tienes un cross-site scripting almacenado.335 BDescargar

Metadatos y privacidad

Una foto recién sacada del móvil indica dónde se tomó y cuál es su orientación. Si no eliminas lo primero, filtras la ubicación de tus usuarios; si ignoras lo segundo, todos los retratos aparecen de lado. Este archivo incluye ambas cosas, para que puedas verificar que tu flujo de trabajo gestiona cada una.

ArchivoQué pruebaTamañoDescargar
exif-gps-orientation.jpgContiene coordenadas GPS (la CN Tower de Toronto) y Orientation 6, que indica girar 90 grados en sentido horario para mostrarla derecha. Úsalo para comprobar tanto que eliminas los datos de ubicación como que respetas la rotación.1 KBDescargar

Texto, codificación y finales de línea

Una marca de orden de bytes (BOM) que se convierte en un carácter visible en la primera columna, campos entrecomillados que contienen comas y saltos de línea literales, tres terminadores de línea distintos en un mismo archivo y ningún terminador al final. Todo esto es normal en los archivos que te envían los usuarios reales.

ArchivoQué pruebaTamañoDescargar
bom-crlf-quoted.csvUna marca de orden de bytes (BOM) UTF-8, finales de línea CRLF, campos entre comillas que contienen comas, comillas dobles escapadas, un salto de línea literal dentro de un campo y nombres no ASCII. Si el BOM aparece en la cabecera de tu primera columna, ahí está el fallo.180 BDescargar
unicode-torture.txtMarcas combinantes, un espacio de ancho cero, un carácter de anulación de derecha a izquierda, caracteres de los planos suplementarios y un emoji de bandera de seis puntos de código. Prueba el recuento de longitud, el truncado y la normalización.565 BDescargar
mixed-line-endings.txtLF, CRLF y un CR suelto en el mismo archivo, sin terminador en la última línea. Aquí el código que cuenta líneas suele contradecirse a sí mismo.107 BDescargar
no-trailing-newline.txtTermina sin salto de línea. Si añades contenido a este archivo sin comprobarlo, dos registros acaban unidos en uno.48 BDescargar

Nombres de archivo complicados

La prueba está en el nombre, no en el contenido. Los nombres largos desbordan las columnas de la base de datos y los límites del sistema de archivos; los nombres que no son ASCII rompen las cabeceras Content-Disposition, el escapado de URL y la diferencia entre Unicode compuesto y descompuesto en macOS.

ArchivoQué pruebaTamañoDescargar
文件名-with spaces-🌲.txtCaracteres chinos, espacios y un emoji en el nombre de archivo. Prueba la codificación de Content-Disposition, el escapado de URL y la normalización Unicode descompuesta de macOS.194 BDescargar

Límites estructurales y de recursos

Archivos válidos que son incómodos más que defectuosos: un archivo comprimido con diez mil entradas, JSON anidado a más profundidad de la que admiten por defecto la mayoría de los analizadores y un archivo comprimido cifrado. Ninguno es un ataque: son las formas que hacen que una implementación ingenua se quede sin algún recurso.

ArchivoQué pruebaTamañoDescargar
many-entries-10000.zipDiez mil entradas pequeñas que en total ocupan menos de 1 MB sin comprimir. Prueba el análisis del directorio central y el coste por entrada. A propósito, no es una bomba ZIP.1.6 MBDescargar
deeply-nested.json512 niveles de anidamiento. Es JSON válido, pero más profundo de lo que muchos analizadores permiten por defecto, y lo bastante como para agotar la pila de un analizador recursivo.3 KBDescargar
encrypted-password-test.zipCifrado con ZipCrypto; la contraseña es test. La extracción sin contraseña debe fallar limpiamente en lugar de producir basura.292 BDescargar

Inyección de fórmulas en hojas de cálculo

Una celda CSV que empieza por =, +, - o @ se interpreta como fórmula al abrir el archivo en Excel, Google Sheets o LibreOffice. Si tu aplicación exporta a CSV texto introducido por los usuarios sin escapar esos prefijos, estás distribuyendo su entrada como fórmulas ejecutables. Las cargas de estos archivos solo calculan operaciones aritméticas inofensivas.

ArchivoQué pruebaTamañoDescargar
formula-injection.csvCeldas que empiezan por =, +, - y @, que las hojas de cálculo tratan como fórmulas. Las cargas calculan operaciones aritméticas inofensivas y una crea un enlace a este sitio. Ninguna ejecuta un comando.189 BDescargar

Modelos 3D: mallas vacías, defectuosas y engañosas

El código que trabaja con mallas suele dar por hecho un modelo cerrado, de tamaño razonable, con la orientación de caras correcta y al menos un triángulo. Los usuarios suben todo lo demás. Aquí tienes la malla vacía, triángulos de área cero y con las caras invertidas, una malla no manifold, coordenadas demasiado grandes o demasiado pequeñas para que float32 las gestione bien, un GLB cortado a mitad de la subida, un STL cuya cabecera miente, un GLB que se hace pasar por STL y el STL binario que engaña a la clásica comprobación de “si empieza por solid, es ASCII”. Están en la carpeta 3D; los ejemplos 3D válidos están en la categoría de modelos 3D.

ArchivoQué pruebaTamañoDescargar
empty-mesh-zero-triangles.stlUn STL binario estructuralmente válido: la cabecera de 80 bytes y un recuento de triángulos de 0, nada más (84 bytes). El código de caja delimitadora, centrado y miniaturas a menudo divide por cero o accede a un array vacío en este caso.84 BDescargar
empty-scene-no-meshes.glbUn binario glTF 2.0 válido con una escena y un nodo vacío, pero sin mallas, buffers ni materiales. Pasa el validador de Khronos. Los visores deben mostrar una escena vacía, no lanzar una excepción.276 BDescargar
degenerate-triangles.stlUn cubo de 10 mm más seis triángulos de área cero: vértices repetidos, puntos colineales y una astilla por debajo del épsilon. El cálculo de normales divide aquí por una longitud cero, y de ahí salen las normales NaN.984 BDescargar
flipped-normals-inside-out.stlUn cubo de 10 mm con todos los triángulos en sentido horario y las normales almacenadas apuntando hacia dentro. Se ve negro o invisible con la eliminación de caras traseras (back-face culling), y su volumen con signo es negativo.684 BDescargar
non-manifold-open-box-and-fins.stlUna caja sin tapa (un borde abierto) más dos aletas que comparten cada una una arista con otras dos caras. No se puede imprimir tal cual; los slicers y las herramientas de reparación deben señalar ambos problemas.684 BDescargar
huge-coordinates-1e7.stlUn cubo de 100 unidades centrado a diez millones de unidades del origen. A esa magnitud, float32 solo puede representar números enteros, así que aparecen problemas de precisión, del plano lejano de la cámara y del encuadre automático.684 BDescargar
tiny-scale-1e-6.stlUn cubo de una millonésima de unidad de lado. Leído en milímetros mide un micrómetro: prueba las comprobaciones de tamaño mínimo, la deducción de unidades y cualquier épsilon usado para fusionar vértices.684 BDescargar
extreme-float-values.stlCoordenadas de vértices de ±3.0e38, cerca del máximo de float32, y un triángulo formado por valores subnormales de 1e-40. El archivo no contiene NaN ni Infinity, pero calcular el tamaño de la caja delimitadora en float32 desborda a Infinity.234 BDescargar
truncated.glbEl primer 60 por ciento de un GLB con texturas válido. La cabecera sigue indicando la longitud completa y el bloque BIN termina antes de tiempo, que es justo el aspecto de una subida interrumpida de un GLB.80 KBDescargar
wrong-triangle-count-header.stlUn STL binario cuyo recuento uint32 indica 1000 triángulos cuando el archivo contiene 12. Un lector que se fía del recuento lee más allá del final; uno estricto rechaza el archivo porque 84 + 50 × 1000 no coincide con su tamaño.684 BDescargar
actually-a-glb.stlUn GLB auténtico y válido (empieza con los bytes glTF) guardado con extensión .stl. Todo lo que decida según la extensión se lo pasará al analizador de STL.21 KBDescargar
binary-stl-header-starts-with-solid.stlUn STL binario válido cuya cabecera de texto libre empieza por la palabra solid, como hacen varios exportadores reales. Detectar el STL ASCII por ese prefijo envía este archivo al analizador equivocado; compara mejor el tamaño con el recuento de triángulos.684 BDescargar
obj-missing-mtl.objUn OBJ por lo demás válido cuya línea mtllib apunta a un archivo de materiales que no existe. La geometría debe cargarse igualmente con un material por defecto y un aviso, no fallar.914 BDescargar
obj-negative-indices.objUn OBJ válido cuyas caras usan índices negativos relativos (f -3 -2 -1), algo que el formato permite. Muchos analizadores escritos a mano solo admiten índices positivos.675 BDescargar
立方体 cube-modèle-🧊.stlUn cubo válido de 10 mm cuyo nombre de archivo mezcla caracteres chinos, una letra acentuada, un espacio y un emoji. Prueba Content-Disposition, la codificación de URL y las claves de almacenamiento en las subidas de modelos.684 BDescargar

Una lista breve para gestionar subidas

  1. Comprueba un tamaño mínimo además del máximo. Las subidas de cero bytes son el caso que más se pasa por alto.
  2. Determina el tipo a partir de los bytes, nunca de la extensión ni del tipo de contenido que envía el navegador. Ambos los controla el atacante.
  3. Sirve las subidas de los usuarios desde un dominio aparte, o con Content-Disposition: attachment y X-Content-Type-Options: nosniff, para que un archivo que resulte ser HTML no pueda ejecutarse en tu origen.
  4. Elimina los datos EXIF antes de publicar una imagen, y aplica la etiqueta de orientación antes de eliminarlos.
  5. Escapa los =, +, - y @ iniciales al escribir texto de usuarios en un CSV.
  6. Fija límites explícitos al número de entradas de un archivo comprimido, al tamaño total descomprimido y a la profundidad de recursión del analizador, y devuelve un error claro cuando se alcance alguno.
  7. Decide qué debe pasar con un archivo subido a medias y pruébalo con los archivos truncados de aquí en lugar de darlo por supuesto.

Preguntas frecuentes

¿Son peligrosos estos archivos?

No. No hay bombas zip, ni entradas con path traversal, ni ejecutables, ni macros, ni cadenas de prueba de malware. El archivo más grande se descomprime en menos de un megabyte. Los fallos son reales (una imagen truncada está realmente truncada), pero nada de aquí ataca al equipo que lo abre. Las fórmulas de la hoja de cálculo calculan operaciones aritméticas inofensivas en lugar de ejecutar un comando.

¿Para qué sirve el archivo HTML con extensión .jpg?

Es el archivo más valioso del paquete. Si tu aplicación lo acepta como imagen, lo almacena y más tarde lo vuelve a servir con un tipo de contenido deducido de su contenido, el navegador lo renderiza como una página de tu dominio. Eso es un cross-site scripting almacenado a través de una subida de imagen. Aceptar el archivo no es un problema; servirlo de vuelta como HTML, sí.

¿Por qué el CSV tiene celdas que empiezan por un signo igual?

Porque Excel, Google Sheets y LibreOffice interpretan una celda que empieza por =, +, - o @ como una fórmula. Si tu aplicación exporta a CSV texto introducido por usuarios sin escapar esos prefijos, lo que alguien escribió en un formulario llega a la hoja de cálculo de un compañero como una fórmula activa. La solución es anteponer un apóstrofo a esas celdas o entrecomillarlas al exportar.

¿De verdad la foto contiene coordenadas GPS?

Sí: la CN Tower de Toronto, a 43,6426 norte y 79,3871 oeste, más una altitud. También lleva la orientación 6, que indica que el visor debe girarla 90 grados en el sentido de las agujas del reloj para mostrarla derecha. Entre las dos cubren lo que cualquier flujo de imágenes debe hacer bien: eliminar los datos de ubicación antes de publicar y respetar la rotación para que los retratos no salgan de lado.

¿Puedo usarlos en una suite de pruebas automatizadas?

Sí, para eso están. Cada archivo es determinista, su SHA-256 se publica aquí y los enlaces directos tienen cachés de larga duración y cabeceras CORS abiertas. Fija el hash en tu prueba y sabrás al instante si un fixture cambia alguna vez.

¿Encontraste un problema o algo que podría mejorar? Leemos todos los mensajes y lo arreglamos rápido.

¿Necesitas archivos válidos?

La mayoría de las pruebas necesitan un archivo que funcione. También los publicamos: imágenes, vídeo, audio, documentos, archivos comprimidos, datos, fuentes y modelos 3D reales, en tamaños exactos y con hashes publicados.