A Black Rectangle Is Not a Redaction
Every year the same story pops up in the news. A law firm, a government agency or a company publishes a document with sections blacked out. Someone opens the file, highlights the blacked-out sections, hits copy, and pastes the secret text right out.
It is embarrassing and it keeps happening. The reason is that most tools make it easy to draw a black box and difficult to actually remove the information underneath.
Why does the text survive?
A PDF is closer to a set of drawing instructions than to a "document" in the everyday sense.
A line of text in a PDF looks roughly like this (simplified):
BT
/F1 12 Tf
72,700 TD
(Account Number: 4839 2201 5567) Tj
ET
BT begins a text object, Tf picks a font, Td positions it, Tj draws the string, and ET ends the object.
Both sets of instructions live in the same file. The renderer draws the text, then draws an opaque rectangle on top. Visually, the account number is gone. Structurally, nothing was removed.
That means every mechanism that reads the PDF instead of just looking at it will still find the string:
Text selection and copy
Search in the viewer and at the OS level.
pdftotext and other extraction libraries
Search indexing if the file is uploaded anywhere
Accessibility tools reading the text layer
The rectangle only defeats human eyes. It defeats nothing else.
And this isn't a bug. It's the default behavior of the most obvious interaction in many UIs. If your annotation tool has a filled-rectangle shape, a user can create a document that looks redacted but isn't in about four seconds, with no warning.
Now imagine you open that file and draw a black box over the account number. In most tools, you haven't deleted the text. You've just added more instructions: "draw a filled rectangle here."
BT
/F1 12 Tf
72 700 Td
(Account Number: 4839 2201 5567) Tj
ET
q
0 0 0 rg
70 695 180 18 re
f
Q
Both sets of instructions live in the same file. The renderer draws the text, then draws an opaque rectangle on top. Visually, the account number is gone. Structurally, nothing was removed.
That means every mechanism that reads the PDF instead of just looking at it will still find the string:
Text selection and copy
Search in the viewer and at the OS level
pdftotext and other extraction libraries
Search indexing if the file is uploaded anywhere
Accessibility tools reading the text layer
The rectangle only defeats human eyes. It defeats nothing else.
And this isn't a bug. It's the default behaviour of the most obvious interaction in many UIs. If your annotation tool has a filled-rectangle shape, a user can create a document that looks redacted but isn't in about four seconds, with no warning.
The three things that have to be true
Once you stop thinking of redaction as "drawing a black box" it becomes clearer what a safe redaction actually needs to do. A tool can get one or two of these right and still be unsafe, because all three have to work together.
The visual content has to be destroyed, not covered. On export, the affected region has to be rewritten so that the original marks are no longer present in the output — not present-but-hidden. We do this by rasterising and baking the redacted region into the exported PDF, so the sensitive content becomes part of a flattened result rather than sitting underneath something opaque.
Clean up the text layer too. Even with the visuals handled, a PDF usually carries a separate text layer used for search, selection and accessibility. If the sensitive string is still in that layer, nothing has been protected. So a proper redaction has to do two things: remove the text from the visible page, and remove it from the selectable and searchable text layer as well. Only then do copy-paste, search and extraction stop reaching it.
Keep "marked" and "applied" redactions separate. This is where a lot of tools go wrong, and it is the more subtle failure of the three. There are two states:
Marked — the user has drawn boxes over sensitive areas, but nothing has been permanently removed yet. This is editor state, and the user should be able to move, edit or delete these marks.
Applied — the document has been transformed so the original content is actually gone. This is a deliberate, destructive action.
The dangerous bug happens when these two states get blurred. A user sees black boxes, assumes the document is safe, and exports it — but the export path never ran the apply step. The file looks correct and is not.
The coordinate problem
There is a detail underneath all of this that took us longer than expected.
To remove text from the visible layer you need to know which extracted characters correspond to the region the user marked. That is not free. Text extraction gives you strings and geometry; a marked redaction gives you a rectangle. Mapping between them means maintaining a correspondence between extracted characters and their positions on the page.
We render and extract with PDF.js, and we ended up with a shared text builder and a single bounds-for-range function used by both document search and by regex-driven redaction. Which sounds like ordinary refactoring, and it was — but the reason it mattered is that search and redaction were answering the same question, where on the page is this text, and had drifted into two answers.
Two answers to that question are a correctness bug waiting to happen. If search can find a string that redaction cannot locate, you have a tool that will tell a user the sensitive text exists and then fail to remove it.
The regex path is worth mentioning because it addresses a real gap in manual redaction. A person marking boxes by eye will redact the account number they noticed. They will miss the second occurrence on page 9. Pattern-driven redaction over the extracted text catches what visual inspection misses, and it only works if the coordinate mapping is shared and trustworthy.
What this does not solve
I would rather say this plainly than have someone discover it.
The original file is untouched. All of this happens on export. If a user redacts a document and then sends the original instead of the exported copy, nothing has been protected. The workflow has to make the exported file the obvious thing to hand over.
Rasterising has costs. The redacted region stops being vector text. That means it is no longer selectable or machine-readable in that area, which is usually the point, but it also affects file size and accessibility. It is a deliberate trade, not a free win.
Visual redaction is not full document cleaning. Metadata, XMP, embedded attachments, form field values, annotations elsewhere in the file, and revision history are separate surfaces. Blacking out a name on page 3 does nothing about that name sitting in the document title. If you are redacting for a legal or compliance obligation, the page content is one item on a longer checklist.
Scanned documents are a different problem. If the page is an image with no text layer, there is no extraction to work with and no strings to pattern-match. Rasterising the region works; everything that depends on the text layer does not apply.
What I would check tonight
If you ship anything that lets users redact a PDF, three checks, in order:
Export a redacted file and run pdftotext on it. If the redacted string comes back, you are drawing rectangles. This takes thirty seconds and it is the only test that matters.
Try to reach an export with pending, unapplied redactions. If you can, and nothing warns you, that is your most dangerous path.
Search your exported document for the redacted string inside your own viewer. If your search index and your redaction logic disagree about where text is, this is where it shows up.
The distinction worth carrying away is the one that took us too long to state clearly: redaction is a document transformation, not an annotation. The black rectangle is a status indicator. The security property comes from the original information no longer being reachable through the normal mechanisms — extraction, search, copy — and those mechanisms do not care what the page looks like.
We work on TeamSync PDF Viewer, an open-source client-side PDF viewer for React.
If you have hit the copy-paste-recovers-the-text problem from the other side — as the person who found it in someone else's document — I would be interested to know which tool produced it. I suspect the list is short and repetitive.
Top comments (1)
Explore it : github.com/angelbot-ai/TeamSync-PD...