Document security / What is inside it
Files embedded inside a PDF, and what they can carry
A PDF can contain other files inside it, which is useful for machine-readable payloads and is a way for content to travel without being visible.
The exposure
The format supports embedding arbitrary files inside a document. That is deliberate and useful: an electronic invoice can carry a structured data file alongside the human-readable page, so one artefact serves both a person and a system. It also means a document can contain content that no page displays, which matters in two directions. A document you receive may carry something you did not expect, and a document you produce by transforming another may carry an embedded file forward without anybody noticing.
The decisions
Reasons rather than a description of the code. Each one has a default that is fine for a page and wrong for a file somebody keeps.
- Know whether your documents carry embedded files, by inspecting a real one rather than assuming. Producing them is deliberate and inheriting them is not.
- Where a document is built from an existing PDF, check what came along. Embedded files survive operations that only appear to touch the visible content.
- Treat an embedded file in an inbound document as untrusted input, the same as any uploaded file, since nothing about it being inside a PDF makes it safer.
- Where you embed deliberately, keep the embedded payload and the visible page consistent, because a machine reading one and a person reading the other must not disagree.
- Know what this API does: there is no attachment or embedding option on the render, so embedding is a post-processing step in a tool you choose.
- Include an embedded-file check in the same place you check metadata, since both are invisible on the page and both travel with the file.
In practice
A fragment, with the thing that goes wrong kept in a comment where it is the more instructive half.
// Inspect rather than assume: producing embedded files is deliberate,
// inheriting them is not.
const attachments = await listEmbeddedFiles(pdf);
if (attachments.length) {
log.info("document carries embedded files", {
documentId,
names: attachments.map((a) => a.name),
});
}
/* Two directions to worry about:
inbound a document you received may carry a file no page shows.
Treat it as untrusted input, exactly like an upload. Being
inside a PDF makes it no safer.
inherited a document built by transforming an existing one can carry
its embedded files forward. Operations that appear to touch
only the visible content frequently preserve them. */
// The check belongs next to the metadata check: both are invisible on
// the page, both travel with the file.
test("documents carry no unexpected embedded files", async () => {
const pdf = await renderFixture("invoice", "typical");
expect(await listEmbeddedFiles(pdf)).toHaveLength(0);
});
/* There is no attachment or embedding option on this render, so a
deliberate embed is a post-processing step in a tool you choose. If
you do it, keep the payload and the visible page consistent: a
machine reading one and a person reading the other must not
disagree about the amount. */What people do instead
Assuming a PDF is only what it displays. It is a container, and content inside it that no page shows is still content that was delivered, which matters both when receiving documents and when transforming them.
How this is found out
By inspection, or by a security tool scanning attachments. It is invisible in every normal interaction with the document, including a careful visual review of every page.
Frequently asked
Does this page tell me what the law requires?
No, and deliberately not. Retention periods, erasure obligations and residency rules vary by jurisdiction, by industry and by the kind of document, and they change. What these pages describe is the shape of the problem and the mechanisms a system needs in order to implement whatever answer your own advisers give you. Where a genuine tension exists, such as an immutable record against a right to erasure, it is named as a tension rather than resolved.
Why is so much of this about the contents rather than access control?
Because access control decides who can obtain a copy and has no opinion at all about what happens to the copy. Once a document is on somebody's laptop, forwarded to a colleague or printed, every control listed here has already stopped applying to it. What is inside the file is therefore the part that keeps mattering, which is the opposite of the balance you would strike for a page.
How much of this applies at a small volume?
Most of it, because these are decisions rather than infrastructure. Redacting by omitting rather than covering costs nothing. Deciding what goes on a template costs one review. Classification is one object in code. Legal hold and an audit trail are the two that take real work, and both are far cheaper to build before they are requested than under the deadline that comes with the request.
Related security topics
The decisions that depend on each other, then the rest of the same group.
What metadata a generated PDF carries, and how to check
The fields a document format carries alongside its visible content, which are invisible on the page and present in the file.
Why a black rectangle over text does not redact it
The most consequential misunderstanding in document handling: covering text with a shape hides it visually and leaves it entirely intact in the file.
Classifying generated documents so handling rules can apply
Attaching a sensitivity level to each kind of document, which is what makes every other rule in this cluster applicable rather than aspirational.
Personal data in a document that will be emailed
What a document discloses once it is attached to a message, which is more than the recipient asked for and travels further than the message.
Internal information that ends up printed on a customer document
The values that reach a customer-facing document because they were available, which are usually internal identifiers, judgements and debugging aids.
Every document security topic
The full list, grouped by access, contents and what happens afterwards.
What this API actually does
The options and endpoints these decisions are built on, one page each.
Most of these are decisions rather than features, and the cheapest time to make them is before the first document is delivered rather than after one reaches the wrong person.