ASCII smuggled in the Unicode tag block
Invisible characters used two ways: to encode a whole hidden sentence, which the engine strips and decodes back into readable text, and — at scale in phishing since early 2026 — as separators dropped inside ordinary words, so the word survives a reader and matches no word list.
How the text is hidden
The Unicode tag block runs from U+E0000 to U+E007F. The characters U+E0020 to U+E007E map one-to-one onto printable ASCII by subtracting U+E0000, so an arbitrary sentence can be written as a sequence of codepoints that render as nothing; U+E0001 LANGUAGE TAG and U+E007F CANCEL TAG are framing and carry no text. Pasted into any document, the payload sits in the character stream beside ordinary prose with no styling, font or geometry involved. The same characters have a second use that needs no encoding at all. Dropping one inside a word leaves it visually identical while breaking any literal match: "funding" written as fun<U+E0069>ding reads normally and is not the string "funding". Microsoft reported this spelling in finance-themed phishing peaking at 2.37 million messages a day in late February 2026, delivered through a mainstream email-marketing platform. Nothing is encoded and there is no payload to decode — the character is a wedge, and the target is the word list rather than the reader.
Why a model still reads it
There is no format-level property to notice — the payload is text, so every extractor carries it through and a model reads the decoded instruction as part of the document. A person opening the file sees only the visible sentence it was pasted beside. The separator form inverts the usual argument: the danger is not that an extractor carries something through, but that a keyword filter reading the same bytes sees a different word than the person does. Microsoft's own guidance is to strip or normalise tag characters before applying keyword, regex or signature detection, which is what text.canonical has already had done to it — a caller running their own word list over the text we return gets the joined word back.
What we do about it
The pack class unicode-tag matches the whole U+E0000–U+E007F range, is declared highConfidence: true ("never legitimate in a document") and is graded medium by the confidence-band mapping; the characters are stripped from text.canonical and, for DOCX, from the cleaned file. decodeTagBlock then reads the payload back as the ASCII it encodes, and the finding's excerpt carries it as decoded tag-block payload: …. This is the only codepoint class whose content is passed to the instruction-shape matcher — codepointFindings feeds the decoded payload to shapeFor, so a tag-block finding can carry instructionShaped and escalate, which no other family-C class can do because the others have no readable text to match against.
How often it fires
0% of 1,244 real documents — 400 web pages (distinct hosts), 630 PDFs (contracts and web), 150 government Word documents, 65 SEC filings, measured 2026-08-21.
This is an alert-volume number and nothing else. It says how often the alarm sounds on documents as found — not how often it is right, and not whether what it found was harmless. Documents as found may themselves carry concealment. Read it against the population named above rather than as a property of documents in general.
Seen in the wild
A phishing campaign peaking at 2.37 million messages a day split finance keywords with invisible characters from the Unicode Tags block, so keyword filters never matched them while readers saw ordinary words.
Check your own file
Three commands: a key, credit, a verdict.
Start with the API