The file Command: Content Identification Is Not Validation or Trust
Use file for useful format clues without treating magic-byte classification, MIME labels, or filenames as proof of safety or authenticity.
The file command answers a practical question: what type does this implementation infer from a pathname’s metadata and contents? Its answer is useful during incident response, download inspection, and file-format triage. It is not a cryptographic identity check, a complete parser, an antivirus verdict, or proof that a file is safe to process. The format database and heuristic rules influence the result, and a hostile file can be crafted to resemble an expected type while remaining malformed or dangerous.
The classic file implementation performs categories of tests: filesystem metadata tests, fixed-offset or “magic” tests, and language or text heuristics. Usually an earlier successful test determines the output. A directory, FIFO, empty file, or symlink can therefore be described based on filesystem properties before content signatures are considered. For regular files, magic patterns can recognize formats from bytes at specified offsets. Text heuristics then attempt to classify encoding, line endings, or programming languages.
Separate filename, media type, and content
A suffix such as .png is a naming convention, not a content proof. Conversely, a file without a suffix may have a valid PNG signature and structure. file examines content and metadata, but even a likely result such as “PNG image data” only says which rules matched. It does not show that every chunk is well formed, that dimensions are safe for a decoder, or that the file came from a trusted publisher.
MIME output is also implementation-dependent. POSIX defines an -i interface, but the exact string formats and database coverage can differ. GNU and BSD versions have overlapping but not identical options such as --mime-type or -I. Human-readable descriptions can change across database releases. If automation needs an allowlist, pin the implementation and database and treat the output as a preliminary routing hint; validate the object with the parser that will consume it.
For example, a triage workflow may display the type and then compute a digest:
file -- "$candidate"
sha256sum -- "$candidate"
This only records two observations. It does not prove authenticity unless the digest is compared with an expected value obtained through a trusted channel, and it does not validate the structure. For a portable script, check option support and avoid parsing localized human output. Do not let a MIME guess alone choose a privileged handler or an executable path.
Magic databases are policy inputs
file signatures are data-driven. The magic database can be supplied or overridden, and different installations can report different classifications. A user-specific magic file may alter results; reproducible investigations should record the file version, database path, and relevant environment. Administrators who deploy custom magic rules should review precedence, offsets, indirect tests, and regex resource use. An overly broad rule can classify unrelated files incorrectly, while a missing rule can leave a known format as generic data.
The program may inspect only part of a large file for some heuristics. A signature near the beginning is not a checksum over the entire object. Compressed-file inspection can invoke decompression logic or consume substantial resources, depending on options and implementation. Treat files from untrusted sources as hostile parser input. Apply size, CPU, and memory limits where practical, and avoid options that invoke external decompressors unless that behavior is explicitly reviewed.
Symlinks and special files matter
By default, behavior around symlinks can vary by implementation and environment. GNU file supports options to follow or not follow links, and POSIXLY_CORRECT can affect GNU behavior. A link’s own type and its referent’s content are different observations. Specify whether the investigation is about the link object or the target, and do not infer that a displayed classification refers to the same object that a later command will open.
Special files deserve caution. Reading a FIFO can block, a device may have side effects, and a socket is not a normal byte stream. Some file implementations avoid reading special files unless asked to do so; flags that force content inspection change that risk. Check stat or another filesystem-type API before content reads in automated triage, and run untrusted inspection with least privilege. A race can still replace a path between the metadata check and the open, so security-sensitive applications should use file descriptors and appropriate kernel APIs instead of shell sequences.
An evidence-based inspection pipeline
For a release artifact, verify the expected checksum or signature first using a trusted manifest, inspect metadata, run file for a quick classification, and then parse the object with the intended consumer in a sandbox. Preserve the original bytes and log tool versions. If a format has a strict schema, run a validator that rejects malformed structures rather than accepting a heuristic label. If the object is a script, inspect its interpreter line and syntax under the target runtime; “shell script text” does not prove that the script is safe or compatible.
For incident response, compare the path’s inode, ownership, mode, timestamps, digest, and content signature with a known baseline. A correct file result can support a hypothesis, but not provenance. To establish identity, use signed metadata or a trusted cryptographic digest; to establish safety, apply format-specific validation and threat analysis. The command is best used as one observability signal among several, not as an authorization decision.
Keep detection separate from admission control
An upload service may need to reject formats outside an allowlist. file can assist with triage, but admission should combine independent checks: enforce a byte-size limit, validate the declared media type and the detected type against policy, parse the complete document with a maintained library, and reject ambiguous or malformed inputs. If the application accepts a container format, inspect its entries and expansion ratio rather than trusting the outer signature. Archive bombs, decompression bombs, parser vulnerabilities, and polyglot files are outside the scope of a magic-byte guess.
Do not use filename extension as an alternative truth source. Attackers can change suffixes, and a valid format can be embedded inside another format. If a workflow must preserve user-provided names, store content under an opaque server-generated identifier and retain the original label only as metadata. The object store’s content-type header should be assigned from the validated application policy, not blindly copied from file output.
Treat custom rules as sensitive configuration
Magic rules can contain offsets, masks, string comparisons, and nested tests. A custom rule set changes classification results for every process that loads it. Review its origin and permissions, pin the expected database package, and compare output before and after an update using a representative corpus. Changes to magic data can be operationally significant even when the file binary itself is unchanged.
For repeatable analysis, preserve the complete command line and environment values that can change link-following or database selection. Compare output across the known-good corpus after upgrades. A changed label may be a database refinement rather than a file change, while identical labels do not imply identical bytes. Pair classification with digests and an actual parser’s validation result so investigators can distinguish content changes from rule changes.
Build an explicit validation decision
A defensible decision pipeline names each gate and its evidence: the upload size is within policy; the path is stored under an application-generated name; the object digest is recorded; the detected type is one of the expected candidates; a parser for that type accepts the complete input; and any downstream conversion runs with limited privileges and resources. file can contribute the candidate-type observation, but the policy engine should not treat that observation as an authorization token.
If classifications disagree, preserve the object and investigate rather than applying a permissive fallback. For example, a declared PDF detected as generic data may be malformed, encrypted, truncated, or simply outside the installed magic database’s coverage. The correct action depends on the product’s acceptance rules, not on a guess that the detector is outdated. Record the disagreement in a privacy-safe way, pin the tools for reproducibility, and make any allowlist change reviewable.
Related:
- od for Shell Diagnostics: Inspect Bytes Without Guessing at Text
- sha256sum in Release Pipelines: Integrity, Manifests, and Authenticity
Sources: