How to file magic bytes: a technical guide for developers
- Step 1Validate the upload on arrival — Read the first 16 bytes of every uploaded file using a stream. Compare against a curated signature database — the file-type npm package covers 300+ formats in under 5KB.
- Step 2Cross-check with declared MIME type — If the client sends Content-Type: image/jpeg but bytes spell out MZ\x90\x00 (PE), reject the upload with HTTP 415 Unsupported Media Type.
- Step 3Log mismatches for audit — A mismatch is at minimum an encoding error and at worst an attack attempt. Log the detected type, declared type, file size, and uploader identity.
Frequently asked questions
Which library should I use server-side?+
file-type (npm) for Node.js is the most comprehensive and actively maintained. For Python, python-magic wraps libmagic. For Go, h2non/filetype covers common formats natively.
What is the maximum byte count I need to read?+
Most signatures sit within the first 12 bytes. ZIP and OOXML require checking offset 30 for the local file header. Reading 512 bytes covers virtually every format in the file-type database.
How do I handle compressed formats?+
ZIP, GZIP, BZIP2, ZSTD, and LZ4 all have distinct magic bytes. After type confirmation, decompress to a temp buffer and re-validate the inner file — double-extension attacks nest a PE inside a ZIP.
Privacy first
Every JAD Security operation runs entirely in your browser. Files, passwords, and PGP private keys never leave your device — verified by zero outbound network requests during processing.