Detector de magic bytes MIME | La extensión miente, los primeros bytes no
Un archivo llamado config.exe que en realidad es un ZIP. Un .png que esconde un polyglot. Un adjunto report.pdf cuyos primeros cuatro bytes son 3C 3F 78 6D (<?xml). El nombre del archivo y la cabecera Content-Type mienten; los primeros bytes de un archivo (su número mágico o file signature) no mienten. Esta herramienta lee solo los primeros 64 bytes de un archivo arrastrado, todo dentro del navegador, y los compara contra más de 40 firmas — PNG, JPEG, PDF, contenedores ZIP, MP4, ELF, PE, Mach-O, SQLite, WOFF — para reportar el MIME real.
💡 Sobre esta herramienta
Cuando uno escribe un endpoint de subida de archivos, la primera trampa es creer que basta con validar la extensión. El usuario sube payload.exe renombrado como image.png. La siguiente trampa es confiar en el header Content-Type del multipart: el cliente lo elige, y un atacante elige cómodamente image/png. El método serio es leer los primeros bytes del servidor y comparar contra una tabla de números mágicos, que es lo que hacen file(1) en Linux y python-magic en Python por debajo.
Esta herramienta hace exactamente esa comprobación, pero dentro de tu navegador. El archivo se lee con FileReader.readAsArrayBuffer limitado a 64 bytes; no se sube nada, no se hashea, no hay telemetría. Los bytes que coinciden quedan resaltados en verde sobre el preview hexadecimal, y se muestra la regla de firma exacta — así puedes copiar 89 50 4E 47 0D 0A 1A 0A directamente a un fixture de test o a una regla de Snort.
Los contenedores ZIP reciben una tarjeta de aviso adicional. PK\x03\x04 puede ser un .zip plano, pero también .docx, .xlsx, .pptx, .odt, .epub, .jar, .apk o .kmz — todos comparten el local-file header del ZIP. Si no tienes el archivo a mano y solo cuentas con los primeros bytes copiados de un volcado forense, está el modo "pegar hex": pegas FF D8 FF E0 y obtienes JPEG.
🧐 Preguntas Frecuentes
Q. ¿Por qué solo 64 bytes? Casi todas las firmas modernas caben en los primeros 16 bytes. ISO 9660 es el outlier famoso — su firma vive en el offset 0x8001 — pero si tienes que inspeccionar imágenes ISO en un navegador hay herramientas mejores. Limitar a 64 bytes también significa que una imagen de disco de 1 GB se analiza en microsegundos: nunca se carga el resto.
Q. El resultado dice "ZIP container" — ¿cómo sé qué contenedor exactamente?
No puedes saberlo solo con los primeros bytes. .docx, .xlsx, .pptx, .odt, .epub, .jar, .apk, .kmz y .zip mismo comparten 50 4B 03 04. Se diferencian por las entradas internas del archivo, no por la cabecera. Para distinguirlos, descomprime y mira el primer listado: [Content_Types].xml es Office Open XML, META-INF/MANIFEST.MF es JAR, META-INF/CERT.SF es APK, y mimetype como primera entrada es ODT/EPUB.
Q. ¿Detecta archivos polyglot?
No como una comprobación dedicada. El matcher recorre la tabla de firmas y devuelve la primera coincidencia, así que un archivo simultáneamente válido como PDF y JAR será reportado como el que aparezca antes en la tabla. El único caso que sí se señala explícitamente es la ambigüedad de contenedor ZIP (docx vs xlsx vs jar vs apk vs epub vs odt), mediante la tarjeta de aviso. Para análisis polyglot serio, usa binwalk o file -k (keep going).
Q. ¿Cómo funciona el aviso de extensión no coincidente?
Extrae el sufijo del nombre con la regex /\.([a-z0-9]{1,8})$/ y lo compara contra la lista de extensiones del formato detectado. Si invoice.pdf produce 50 4B 03 04 (ZIP), aparece un aviso rojo .pdf vs .zip/.docx/.xlsx/.... Sirve mucho cuando un frontend te pasa "el PDF" y curl te responde application/zip.
Q. ¿Detecta un archivo de texto plano?
El texto plano no tiene firma fija, así que cae en "ninguna firma conocida coincide". XML/SVG (<?xml), RTF ({\rtf) y Postscript (%!) sí se detectan porque empiezan con literales ASCII concretos. Los BOM de UTF-8/UTF-16 no están en la tabla de firmas actual.
Q. ¿El archivo sale de mi máquina?
No. Los primeros 64 bytes se leen a un Uint8Array local, no se envían por la red, y el handle del archivo se descarta apenas se renderiza el resultado. Lo puedes confirmar en DevTools: no se dispara ningún fetch ni XHR durante la detección. Seguro para analizar adjuntos sospechosos que no puedes subir a ningún sitio.
📚 Datos Curiosos
La referencia más rica sobre firmas de archivo sigue siendo la tabla de Gary Kessler, que cataloga más de 700 formatos y es la fuente que citan la mayoría de los autores de reglas YARA. La lista de Wikipedia "List of file signatures" se mantiene al día con los contenedores nuevos — el frame magic 28 B5 2F FD de ZSTD, el ftyp avif (66 74 79 70 61 76 69 66) en offset 4 de AVIF, y los nuevos perfiles EBML de MKV/WebM. La rareza más citada sigue siendo el Microsoft Compound Document D0 CF 11 E0 A1 B1 1A E1 — medio kilobyte de estructura bajo esa cabecera aparece cada vez que alguien abre un .doc o .xls de antes de 2007.
En la comunidad hispanohablante, los CTF de la conferencia argentina Ekoparty y la española RootedCON suelen incluir retos de polyglot y file-carving donde el primer paso siempre es leer la magic byte para entender qué demonios es el archivo entregado. Herramientas como binwalk (popular entre quienes vienen del mundo del firmware y los CTF de hardware), foremost (para recuperación forense), y hachoir (Python, muy querido en la docencia universitaria) comparten el mismo principio: la primera línea de defensa contra archivos malformados es saber qué dicen sus primeros bytes, no qué dice quien lo envió.