Patch diffing Adobe Acrobat PDF prototype pollution

Patch diffing Adobe Acrobat PDF prototype pollution

The diff across Acrobat Reader builds shows three separate problems, not one broad mistake. Each path starts with untrusted object state and ends inside code that assumed it was dealing with ordinary values. That assumption is where the damage sits.

Where the polluted prototype reaches Acrobat’s trusted JavaScript

The first path sits in SilentDocCenterLogin, where swConn was treated as a name that could be resolved from scope rather than a local value. Once prototype pollution influences lookup, inherited keys can stand in for data the code thought it owned. That is a bad place for privileged JavaScript to be guessing.

Collab.isFirstLaunch, Collab.getUserIDFromStore, and Collab.swConnect all live in the collaboration flow, and the dangerous part is the privilege boundary around them. The code runs inside a trusted block, so a fake swConn can push execution into the wrong object path and still look like a valid workflow step. That is how a polluted prototype turns into input for code that should never have trusted it.

SilentDocCenterLogin and the undeclared swConn lookup

An undeclared identifier is not just sloppy style here. It becomes a lookup problem, and lookup problems inside privileged JavaScript are rarely polite. The patched change turns swConn into a real local variable, which closes the inheritance route.

That matters because attacker-controlled prototype keys can fill gaps that the code never intended to leave open. In this case, the fake object can influence the next call in the chain and send the trusted path towards a different helper, including SOAP-related handling. Once the wrong object is in play, the rest of the logic is just carrying it forward.

How inherited keys turn into privileged workflow input

Inherited keys are dangerous when code enumerates or dereferences them without checking ownership. A polluted prototype can supply names that the application later treats as real configuration, connection state, or button metadata. Trusted code then does the attacker’s bookkeeping for them.

Adobe’s own trust model makes this worse because the JavaScript runs with elevated behaviour in places that look routine from the outside. A malicious PDF does not need to own the whole application. It only needs one path that turns object inheritance into trusted input.

The two other patched paths that matter in practice

The other two fixes are a bit more direct. One builds JavaScript from dialog button data. The other accepts values that were supposed to be strings and then uses them as if type checks had never existed. Both are the sort of bug that works fine until somebody hands it a strange object.

ANFancyAlertImpl and the generated button handlers

ANFancyAlertImpl used enumerated button keys to generate handler source, then passed that source into eval. That is a straightforward way to turn data into code, and it is also exactly the sort of construction that collapses when prototype pollution feeds it unexpected keys.

The vulnerable pattern was close to this:

desc[bid] = eval('(function(dialog) { dialog.end('' + bid + ''); })')

A polluted object can shape the buttons list, which shapes the generated handler. Once the handler source is built from attacker-controlled button identifiers, the code path becomes a JavaScript execution problem rather than a dialog problem. The patch moves away from source construction and into a closure parameter, which is the right kind of boring.

ANShareFile and the string-like values that were never just strings

ANShareFile sits inside a trusted function and still trusted fields that were meant to behave like primitive strings. The weak point is object-to-string confusion. Values such as doc.path, props.originalPath, props.savePath, decodedURL, and doc.documentFileName can all arrive as something more awkward than a plain string.

That matters because later string operations assume primitive behaviour. If an object slips through, the code may invoke conversion hooks or follow a path the developer never meant to expose. The patch tightens the check so doc.path has to be a primitive string before later operations use it.

What the diff shows about exploitability and fix quality

The exploitability picture is not subtle. Adobe treated all three issues as critical, and the listed impact included arbitrary code execution and user information leak from a malicious PDF. The affected builds covered Acrobat DC, Acrobat Reader DC, and Acrobat 2024 on Windows and macOS.

The patch quality looks uneven in one place. SilentDocCenterLogin had an earlier fix that appears to have been incomplete, which is a familiar smell in prototype pollution work. One bad lookup can survive the first pass if the patch closes the obvious object path but misses the inheritance behaviour behind it. The later diff makes the local binding explicit, which is the sort of change that should have been there the first time.

ANFancyAlertImpl and ANShareFile look more complete on the face of it because they address the mechanism, not just the symptom. One removes source generation from handler construction. The other refuses to trust object-like values where strings were expected. Both are the sort of changes that stop the same class of bug from reappearing in a slightly different coat.

What to check in Acrobat and Reader builds after patching

Patch level matters more than the product name here. Acrobat Reader 26.001.21367 and earlier was in scope for CVE-2026-34621, while 26.001.21411 and earlier were in scope for the later two issues. That means the build number is the first thing to check, not the marketing label on the splash screen.

After patching, check that collaboration and dialog paths no longer accept inherited state as if it were local data. In practice, that means the fix should stop prototype keys from reaching privileged JavaScript, stop generated handlers from being built out of button identifiers, and stop string-only paths from accepting object values. If a malicious PDF can still steer those checks, the patch is not doing enough.

Related posts

Weekly Tech Digest | 06 Jul 2026

Stay updated with the latest in tech! This digest covers AI ethics, auto industry shifts, and the impact of politics on technology, exploring today's pressing issues.

wolfCOSE zero-allocation parsing in embedded C

wolfCOSE looks sensible only if you care about what your firmware actually has to carry. I like that, because on small targets the wrong crypto feature can cost more than the message itself, and there...

restic | v0.19.1

restic v0 19 1: safer FUSE mounts and mountpoint checks, robust backup source and exclude handling, clearer CLI JSON output, Windows SFTP deletion fixes