Noroboto and the PDF that lied twice | LegalQuants Blog
Noroboto and the PDF that lied twice<br>Alexios vdSK<br>3h ago (edited)
h1]:text-3xl [&>h1]:font-serif [&>h1]:font-bold [&>h1]:text-[#1a1a1a] [&>h1]:mt-10 [&>h1]:mb-4 [&>h2]:text-2xl [&>h2]:font-serif [&>h2]:font-semibold [&>h2]:text-[#1a1a1a] [&>h2]:mt-8 [&>h2]:mb-3 [&>h3]:text-xl [&>h3]:font-medium [&>h3]:text-[#1a1a1a] [&>h3]:mt-6 [&>h3]:mb-2 [&>p]:mb-5 [&>p]:leading-[1.8] [&>blockquote]:border-l-4 [&>blockquote]:border-[#d4a853] [&>blockquote]:pl-5 [&>blockquote]:py-3 [&>blockquote]:my-6 [&>blockquote]:italic [&>blockquote]:text-[#4b5563] [&>blockquote]:bg-[#faf7f2] [&>blockquote]:rounded-r-lg [&>pre]:bg-[#1a1a1a] [&>pre]:text-[#e8e4dc] [&>pre]:p-5 [&>pre]:rounded-lg [&>pre]:my-6 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:overflow-x-auto [&>ul]:list-disc [&>ul]:pl-6 [&>ul]:my-5 [&>ol]:list-decimal [&>ol]:pl-6 [&>ol]:my-5 [&_li]:mb-2 [&_li]:leading-relaxed [&_a]:text-[#d4a853] [&_a]:underline [&_a]:decoration-[#d4a853]/30 [&_a:hover]:text-[#b8923f] [&_a:hover]:decoration-[#b8923f] [&_img]:max-w-full [&_img]:h-auto [&_img]:rounded-xl [&_img]:my-6 [&_img]:shadow-sm [&_hr]:my-10 [&_hr]:border-t-2 [&_hr]:border-[rgba(26,26,26,0.1)] [&_s]:line-through [&_s]:text-[#9ca3af] [&_strong]:font-semibold [&_strong]:text-[#1a1a1a] [&_em]:italic">Noroboto and the PDF that lied twice<br>What if your AI and you are using a different source of truth when handling PDFs?<br>By Alexios van der Slikke-Kirillov on behalf of the LegalQuants RED TEAM.<br>You probably have heard of, are considering, or have set up an ingestion, triaging and classification pipeline that classifies documents on the basis of an LLM call, and you probably use that pipeline for important business. Maybe you have a system that allocates certain non-material matters to juniors in your team; maybe you have a system that routes approvals depending on specific thresholds; maybe you have a quarterly dashboard that uses actual underlying documents as the source of truth; maybe you are using AI for due diligence summaries or maybe your legacy document management software provider has now sold you that their solution is now “powered by AI”.<br>In that endeavor, until now, your main reliability concern was probably “hallucinations”.<br>What this article addresses is much more concerning than “hallucinations”, which, most of the time, at least in my personal view and experience, are due to an undisciplined human operator. What we will be discussing here is just the second episode of a series. A series that shows how your AI use cases may be rendered useless, unless you have set appropriate defenses.<br>Last week, the LegalQuants RED TEAM revealed Noroboto, and how creating a new malicious font definition which is embedded in a word document could fool you, by tampering with the information that you get from your AI (please see here: https://tritium.legal/blog/noroboto).<br>This week, we decided to take this school of thought a bit further up the trust chain, by experimenting with the document that most people use as the final and auditable version in most corporate processes: the PDF.<br>This article opens with (1) a short “PDF anatomy” to unpack what this format actually entails. It then addresses (2) the attack mechanism, the (3) empirical observations, and the (4) updates we have made to Noroboto itself.<br>1. Anatomy of a PDF<br>Below are two facts about the PDF format that makes this vulnerability possible, and which are not widely known outside specific technical circles.<br>A PDF stores drawing commands, not text. If a PDF says “Hello”, the text “Hello” is not stored as the bytes “H e l l o”. Rather, to keep it simple, it is stored as a sort of code that tells your PDF reader what to draw for you to see (which in this case would be visible to you as the letters “Hello”).
A second, optional table exists for text extraction. Because the rendered shape (“H”) and the underlying human meaning (“the letter H”) have no inherent link in PDF (from its perspective, the renderer simply draws glyph shapes, as instructed by the code) PDF defines an optional table for the benefit of copy-paste, screen readers, accessibility tooling, and… your downstream AI text-extractor. This table, attached to each font, is called the “/ToUnicode CMap”.
Figure 1 (created with Claude Code): The data flows out of a font dictionary. The renderer consults the glyph mapping. The extractor consults the /ToUnicode CMap. The PDF specification defines both; it does not state a consistency relationship between them.<br>2. The attack mechanism<br>Build a PDF such that the page visibly contains “the Settlement amount is $1,400,000.” drawn with a standard font, while the font dictionary’s /ToUnicode CMap maps the same character codes that spell "$400." followed by six characters that the extracting AI discards.<br>Nothing in the PDF protocol requires the text and the glyphs to match. So, nothing is out of order in the document, no invisible characters appear in the content stream,...