Docento.app
Close-up of a circuit board
All Posts

Malicious PDFs and How to Stay Safe

By The Docento.app TeamPublished 7 min read
Try Docento's free PDF editorNo sign-up, 100% private — sign, annotate, and stamp PDFs in your browser.Open the editor

PDF is a container format with an execution model, an embedded-file mechanism, a scripting engine and a network-capable link system. That combination is genuinely useful and genuinely exploitable, which is why PDFs have been an attachment-borne attack vector for two decades. This is a practical account of what the attacks look like in 2026, which of them still work, and what actually reduces your risk — as opposed to what merely feels careful.

The three categories of PDF attack

Almost everything falls into one of three buckets, and they need different defences.

1. Exploiting the reader. A malformed file triggers a memory-safety bug in the PDF parser, achieving code execution. This is the classic "opening the PDF infected me" scenario. It requires a vulnerability in your specific viewer, which is why it is much rarer than it was — modern viewers are sandboxed and mostly memory-safe in their hot paths — but not extinct. Font parsers, image decoders and JavaScript engines are the usual targets.

2. Using the PDF as a delivery wrapper. The file is well-formed and harmless in itself; it carries something else. An embedded executable, a .docm attachment, a launch action, or a link to a payload. The PDF is the envelope, not the weapon.

3. Using the PDF as a social-engineering canvas. By far the most common today. A convincing invoice, a fake DocuSign notice, a "your document is protected, click to view" page with a link to a credential-harvesting site. No exploit at all — the document is doing exactly what PDFs do, and the attack is entirely in what it persuades you to do next.

Category 3 is where the volume is. Most defensive advice focuses on category 1, which is the one your viewer already handles reasonably well.

The specific features that get abused

JavaScript. PDFs can carry scripts that run on open. Legitimately this drives form calculations and validation — see how to add calculations to a PDF form — and illegitimately it has been the delivery mechanism for a long line of Acrobat exploits, typically by heap-grooming before triggering a parser bug. The risks are covered in detail in PDF JavaScript security risks.

Embedded files. A PDF can carry arbitrary attachments. Combined with a /Launch action or a persuasive "double-click here to open the invoice" instruction, this delivers executables past filters that only inspect the outer file type. See PDF attachments and embedded files.

Launch and URI actions. /Launch asks the viewer to run an external program; modern viewers block or heavily warn on it. /URI opens a link — unremarkable, and the backbone of PDF phishing.

Auto-actions. /OpenAction runs something when the document opens. Legitimately it sets the initial view; illegitimately it triggers script or a network fetch without any interaction.

Form submission. An AcroForm can POST its data to a URL. A form that looks like a login page and submits credentials to an attacker's server is a complete phishing kit inside a document.

XFA forms. A separate, XML-based form architecture with its own parser and its own history of vulnerabilities. Deprecated in PDF 2.0 and disabled by default in most current viewers, which is a net gain for security. See XFA forms explained.

Embedded fonts and images. Not features being abused so much as complex parsers being attacked. Font rasterisers in particular have a long CVE history.

What actually reduces risk

In rough order of effectiveness:

Keep the viewer updated. Unglamorous and by far the most effective single measure. Nearly every category-1 attack targets a patched vulnerability, because attackers know how long people delay updates. This applies to Acrobat, Foxit, and your browser equally.

Use a sandboxed viewer. Chrome, Edge and Firefox render PDFs inside the browser sandbox, and Firefox's viewer is written in JavaScript rather than C — it cannot have a memory-safety bug in its parser because it has no memory to corrupt in that sense. Acrobat's Protected Mode (Windows) is on by default and should stay on. Opening an unexpected attachment in a browser rather than a desktop application is a real, meaningful reduction in exposure.

Turn off JavaScript in your PDF reader. In Acrobat: Preferences → JavaScript → uncheck Enable Acrobat JavaScript. The cost is that a small number of interactive forms stop calculating; the benefit is removing an entire attack surface. For most people this is a straightforwardly good trade. Browser viewers either do not run PDF JavaScript at all or run it in a heavily restricted form.

Do not open attachments inside PDFs. If a document contains an embedded file, treat it exactly as you would an unexpected email attachment — because that is what it is, with an extra layer of wrapping to slip past filters.

Check where links go. Hover before clicking, and be sceptical of any PDF whose primary content is "click here to view the document". A real invoice is an invoice; a PDF whose only purpose is to hold a link is a redirect with extra steps.

Distrust "protected document" pages. The pattern — a blurred background image with a login prompt over it — is phishing, essentially always. PDF encryption prompts for a password in the viewer's dialog, not on a page. Knowing what genuine encryption looks like helps: PDF encryption explained.

Sanitise files you must open but do not trust. Rendering a PDF to images and rebuilding it strips scripts, embedded files and actions along with everything else interactive. qpdf --qdf plus manual inspection, Ghostscript reprocessing, or Dangerzone (a purpose-built open-source tool that converts documents to a safe rendition inside a container) all do a version of this. See ghostscript introduction.

Inspecting a suspicious file without opening it

If you want to know what is inside before rendering it:

  • pdfid.py (from Didier Stevens' tools) reports counts of /JS, /JavaScript, /OpenAction, /Launch, /EmbeddedFile, /AA and similar. A document with no reason to contain JavaScript that contains JavaScript is worth a second look.
  • pdf-parser.py, from the same toolkit, walks the object structure so you can read what a suspicious object actually contains.
  • qpdf --qdf --object-streams=disable in.pdf out.pdf rewrites the file into a human-readable form where you can inspect strings and actions in a text editor. See qpdf introduction.
  • mutool show file.pdf trailer/Root for the catalogue, including /OpenAction and /Names.
  • VirusTotal, with the usual caveat that uploading a file publishes it — never do this with anything confidential.

Understanding what you are looking at is easier with PDF internals: objects and streams as background.

For organisations

If you are responsible for other people's exposure rather than your own:

  • Strip active content at the gateway. Content disarm and reconstruction (CDR) products rebuild every inbound PDF without scripts, embedded files or actions. This defeats categories 1 and 2 essentially completely and is the single highest-leverage control available.
  • Block /Launch and embedded executables at the mail gateway.
  • Standardise on a sandboxed viewer and manage its settings centrally, including JavaScript.
  • Train for category 3, since that is what will actually arrive. The tell is almost never the file; it is the pretext.
  • Do not rely on file-type filtering. A PDF can carry anything, and renaming does not change what a parser will do with it.

Keeping perspective

Two things are true at once. PDFs have a real, demonstrated attack surface, and the overwhelming majority of malicious PDFs you will encounter do not exploit anything — they ask you to click a link. An updated, sandboxed viewer with JavaScript disabled handles the technical threats well. The remaining risk is judgement, and no setting addresses that.

Related reading: are online PDF editors safe for the other side of the trust question, and how to share a PDF securely for not becoming the sender of something suspicious.

Summary

Update your viewer, prefer a sandboxed one, turn off PDF JavaScript, treat embedded files like unexpected attachments, and be deeply sceptical of any PDF whose real content is a link. If you need to inspect something first, pdfid.py will tell you in seconds whether a document contains active content it has no business containing — and if you need to open something genuinely untrusted, sanitise it by rendering and rebuilding rather than trusting the parser.

Try Docento's free PDF editor

No sign-up, 100% private — sign, annotate, and stamp PDFs in your browser.

Open the editor

Related Posts