Open a file and something has to decide what it is. That decision happens before any security control does its work, and almost nothing in the path makes it honestly.
The extension says .pdf. The MIME type says application/pdf. The first few bytes look close enough. So the file goes down the PDF path, gets handed to the PDF parser, gets checked by the tools that check PDFs, and everything downstream inherits a decision that was made in the first few milliseconds by reading what the file said about itself.
That is the whole mechanism. The file declares. The stack routes. Nobody verifies.
The one field the sender owns
Every other input in security gets treated as hostile. Headers, form fields, filenames, query strings. We learned a long time ago that anything the sender controls is something the sender can lie about, and we built entire disciplines around not trusting it.
A file’s declared type is the same kind of input. The extension is a string the sender picked. The MIME type is a header the sender set. Magic bytes are the first few bytes of a file the sender wrote. All three are assertions from an untrusted party, and all three are usually accepted without question.
The consequence is not subtle. A file that calls itself a PDF and is actually a ZIP archive gets routed to the PDF path. The archive inspection that would have opened it and looked inside never runs, because the routing decision was made by the thing being routed. The control did not fail. It was never called.
This is why type confusion keeps working. It is not that the tools are bad at their jobs. It is that they were pointed at the wrong job by the file itself.
Zero Trust already solved this, for everything except files
Here is the part that should be uncomfortable.
Zero Trust exists because we stopped accepting self-declared identity. A user saying who they are is not proof. A device saying it is healthy is not proof. A network saying it is internal is not proof. Every one of those claims gets re-verified, every request, because the whole model rests on refusing to take an assertion at face value.
Zero Trust re-verifies every claim a user, a device, or a network makes. Then a file declares its own type and the architecture nods.
Identity, device, and network all get the verification treatment. The file, which is the thing actually carrying the payload or the data, gets a pass on the strength of a three letter extension. It is the one place in a Zero Trust deployment where a self-declaration is still load-bearing.
What checking actually means
The alternative is not exotic. It is the same thing Zero Trust does everywhere else. Derive the answer from evidence instead of accepting the claim.
For a file, that means the verdict comes from the content. Not from the extension, not from the MIME header, not from a signature on the first four bytes, but from what the bytes actually are when you read them.
It also means the type is established by cross verification rather than by any single indicator, because any single indicator can be forged. One header agreeing with itself proves nothing.
And it means the disagreement is the finding. If the structure says ZIP and the name says PDF, that is not a routing problem to be resolved in favor of the name, and it is not an exception to log and move past. A file lying about what it is is not an edge case to be handled. It is a signal, and often the only one you needed.
This is where Zero Trust for Files starts, and everything else depends on it. A control that routes on the declaration is not inspecting the file. It is inspecting whatever the file told it to inspect.
Content over declaration. The file’s account of itself is an assertion from an untrusted party, and it gets treated like one.