← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-34621 · CWE-1321 · Disclosed 2026-04-11

Acrobat Reader versions 24

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a razor blade hidden in the PDF inbox, not a battering ram at your perimeter

CVE-2026-34621 is a prototype-pollution bug in the Acrobat/Reader JavaScript handling path that can end in arbitrary code execution as the logged-in user after the victim opens a crafted PDF. The affected lines are Acrobat DC and Acrobat Reader DC Continuous 26.001.21367 and earlier on Windows/macOS, plus Acrobat 2024 Classic 24.001.30356 and earlier, with Adobe fixing DC/Reader DC in 26.001.21411, Acrobat 2024 Windows in 24.001.30362, and Acrobat 2024 macOS in 24.001.30360.

Adobe's raw score is fair but incomplete. The big downward pressure is real: this is AV:L with UI:R, so the attacker still needs delivery and a user open event; the big upward pressure is bigger: Adobe says it is exploited in the wild and CISA put it in KEV on 2026-04-13, which means the bug has already crossed from lab curiosity into operational tradecraft. Net: keep it HIGH, but treat it operationally like an emergency because the reachable population is huge even if the trigger requires user action.

"Actively exploited and everywhere, but still a click-to-own client bug—not a wormable estate-wide fire."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver a weaponized PDF

The attacker uses a malicious PDF as the delivery vehicle, typically through phishing, chat, web download, or shared storage. Public exploit indexing services already show GitHub PoCs and exploit builders associated with this CVE, so creating a lure file is not the hard part anymore.
Conditions required:
  • Target uses Adobe Acrobat or Reader in an affected version
  • Attacker can reach the user with a file or link
  • The file is not stripped, blocked, or detonated before delivery
Where this breaks in practice:
  • Mail security can quarantine suspicious PDFs
  • Browser-based viewers and safe-view features can break the chain before Reader opens the file
  • Targeted delivery still requires initial contact with a user
Detection/coverage: Email gateways, sandbox detonation, and secure web gateways have decent coverage on the delivery stage, but they detect the lure, not the vulnerable version. Network scanners do not meaningfully see this because Reader is client software, not an exposed service.
STEP 02

Trigger Acrobat's JavaScript engine

Once the victim opens the document in vulnerable Acrobat/Reader, the embedded JavaScript path processes attacker-controlled objects and the prototype-pollution condition is triggered. The weaponized component here is the PDF's embedded script running inside Acrobat's document-processing logic.
Conditions required:
  • Victim opens the PDF in vulnerable Acrobat/Reader
  • JavaScript execution or relevant document actions are allowed by product policy
  • The exploit matches the victim's product track and version
Where this breaks in practice:
  • User interaction is mandatory
  • Protected modes, hardening, or disabled JavaScript may interrupt portions of the chain
  • Version-specific exploit reliability is usually worse across mixed fleets than headlines imply
Detection/coverage: Endpoint telemetry can sometimes see Acrobat spawning child processes or touching suspicious temp paths, but signature coverage for the JavaScript object abuse itself is uneven.
STEP 03

Execute code as the current user

Successful exploitation yields arbitrary code execution in the context of the current user, not instant domain admin. In practice that is enough for a loader, infostealer, or foothold implant, especially on developer, finance, HR, and executive workstations that routinely open outside PDFs.
Conditions required:
  • Exploit succeeds against the installed build
  • User context has enough rights to launch follow-on payloads
  • EDR or application control does not stop child-process or script behavior
Where this breaks in practice:
  • Current-user execution limits blast radius versus a privileged service RCE
  • Application control, EDR, and ASR rules often stop commodity post-exploitation
  • Sandboxing and containerized document handling reduce impact on hardened endpoints
Detection/coverage: Good EDRs should alert on AcroRd32.exe or Acrobat spawning cmd.exe, powershell.exe, script hosts, unsigned children, or unusual network beacons.
STEP 04

Monetize the foothold

From there the attacker pivots into credential theft, data access, or lateral movement using whatever tooling they prefer. The exploit itself is the entry ticket; the real enterprise damage depends on what that user can access and whether downstream controls catch the follow-on activity.
Conditions required:
  • Compromised user has access to sensitive apps, files, or tokens
  • Network egress and identity protections allow payload staging or token abuse
  • No rapid containment from SOC or EDR
Where this breaks in practice:
  • Least privilege and MFA narrow what the compromised user can actually do
  • EDR containment and identity detections often catch the post-exploitation phase
  • Single-host compromise is not the same as unauthenticated server-side takeover
Detection/coverage: This stage is where defenders usually win: EDR, identity analytics, proxy logs, and data access monitoring should all have opportunities to catch it.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusConfirmed exploited. Adobe says it is being exploited in the wild, and CISA added it to KEV. That is the strongest real-world amplifier in this case.
KEV statusKEV-listed on 2026-04-13; due date 2026-04-27. That moves this out of theoretical risk management and into active-incident-prevention territory.
Proof-of-concept availabilityPublic PoC/exploit material appears available. Feedly and CVE aggregation services index GitHub exploit content for this CVE; I would assume copycat weaponization is already underway even if the public code quality varies.
EPSS0.09811 (~9.8%). That's not sky-high, but EPSS tends to understate targeted client-side document exploits compared with internet-facing server bugs. With KEV present, EPSS loses the argument.
CVSS vector readCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H means no auth required, low technical complexity, but the victim must open the file. The AV:L here is really 'local execution through a document-open event,' not 'needs shell access to the box.'
Affected versionsAcrobat DC and Acrobat Reader DC Continuous 26.001.21367 and earlier on Windows/macOS, plus Acrobat 2024 Classic 24.001.30356 and earlier.
Fixed versionsAcrobat DC/Reader DC Continuous 26.001.21411; Acrobat 2024 Windows 24.001.30362; Acrobat 2024 macOS 24.001.30360.
Scanning / exposure realityShodan/Censys/GreyNoise are mostly the wrong lens. This is endpoint client software and the CNA corrected the attack vector from AV:N to AV:L on 2026-04-12. Exposure is driven by install base and user PDF workflows, not internet-open ports. That means your EDR/software inventory is a better source of truth than external attack-surface scanners.
Disclosure and reportingPublished 2026-04-11. Adobe credits Haifei Li (EXPMON) for reporting it.
Vendor severity nuanceThere is a label mismatch worth noting: Adobe's bulletin text calls the bug *critical*, while the CNA CVSS base severity for 8.6 is HIGH after Adobe corrected AV:N to AV:L on 2026-04-12.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (9.0/10)

The decisive downward pressure is that exploitation still requires a user to open a malicious PDF in a vulnerable client, so this is not an unauthenticated perimeter break or a wormable service flaw. The decisive upward pressure is stronger than usual: Adobe confirmed active exploitation and CISA KEV listing means attackers are already operationalizing it against a massive installed base.

HIGH Affected versions and fixed versions
HIGH Active exploitation / KEV status
MEDIUM Breadth and maturity of public PoC weaponization

Why this verdict

  • KEV overrides complacency: confirmed real-world exploitation means this is already a practiced attack path, not a hypothetical parser bug.
  • Huge endpoint population: Acrobat/Reader is common across enterprise fleets, so even a client-side bug can produce large incident volume once lures land.
  • Friction audit keeps it out of CRITICAL: AV:L + UI:R means the attacker needs delivery plus an open event; that is materially narrower than pre-auth remote exploitation of an exposed service.

Why not higher?

It is not a no-click, no-auth network service exploit. The attacker still needs a victim to open a crafted PDF in a vulnerable local application, and the resulting execution is in the current-user context, which lowers immediate blast radius compared with privileged server-side RCE.

Why not lower?

Dropping this to MEDIUM would ignore the one fact that matters most operationally: it is already being exploited and is KEV-listed. Also, the population at risk is broad because Acrobat/Reader is common, and delivery by PDF is one of the oldest, most reliable social-engineering channels in enterprise environments.

05 · Compensating Control

What to do — in priority order.

  1. Block risky PDF delivery paths — Immediately tighten email and web controls for inbound PDFs from untrusted senders, newly registered domains, and external file-sharing links. Because this is KEV-listed, deploy this within hours as a temporary guardrail while patch rollout catches up.
  2. Disable Acrobat JavaScript where business allows — If your workflows do not require PDF JavaScript, turn it off through enterprise policy for Reader/Acrobat. That directly attacks the exploit path and should be pushed within hours for high-risk groups such as finance, executives, HR, and externally facing users.
  3. Force safer PDF handling — Route internet-origin PDFs to browser-native viewers, remote browser isolation, or detonation workflows instead of launching local Acrobat by default. For KEV cases like this, make the policy change within hours for unmanaged or higher-risk user populations.
  4. Harden child-process behavior from Acrobat — Use EDR/ASR/application-control rules to block or alert on Acrobat/Reader spawning shells, script hosts, LOLBins, or unsigned child processes. This does not fix the bug, but it cuts off the most common post-exploitation paths and should be enforced within hours.
  5. Prioritize exposed user groups first — If you cannot patch the whole fleet immediately, front-load users who routinely open externally sourced PDFs: accounts payable, legal, recruiting, support, sales, and executives. For a KEV client exploit, risk is driven by document-handling behavior, so target those cohorts within hours.
What doesn't work
  • A WAF does nothing here because the vulnerable component is a desktop document parser, not a web application endpoint.
  • External attack-surface scanning is low value because Acrobat/Reader is not an internet-listening service; your inventory and EDR are the authoritative sources.
  • Relying on MFA alone does not prevent the initial endpoint compromise; it only helps constrain some post-exploitation outcomes.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or via your software-distribution/EDR remote execution framework. Invoke it with python3 check_cve_2026_34621.py on macOS or py check_cve_2026_34621.py on Windows; standard user rights are usually enough, but local admin helps if you want complete registry visibility across machine-wide installs.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cve_2026_34621.py
# Detects vulnerable Adobe Acrobat/Reader versions for CVE-2026-34621.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 1=vulnerable, 0=patched, 2=unknown/error

import os
import re
import sys
import platform
import subprocess
from pathlib import Path

RESULTS = []

THRESHOLDS = {
    'dc_continuous': ('26.001.21411',),
    'acrobat_2024_windows': ('24.001.30362',),
    'acrobat_2024_macos': ('24.001.30360',),
}


def norm(v):
    nums = [int(x) for x in re.findall(r'\d+', str(v))]
    return tuple(nums)


def cmp_ver(a, b):
    aa = list(norm(a))
    bb = list(norm(b))
    n = max(len(aa), len(bb))
    aa += [0] * (n - len(aa))
    bb += [0] * (n - len(bb))
    return (aa > bb) - (aa < bb)


def add_result(product, version, status, note):
    RESULTS.append({
        'product': product,
        'version': version or 'UNKNOWN',
        'status': status,
        'note': note
    })


def assess_product(name, version, os_name):
    lname = name.lower()
    if not version:
        add_result(name, version, 'UNKNOWN', 'No version found')
        return

    # Continuous DC / Reader DC
    if 'reader' in lname and 'dc' in lname:
        if cmp_ver(version, THRESHOLDS['dc_continuous'][0]) < 0:
            add_result(name, version, 'VULNERABLE', f'Patch level required: >= {THRESHOLDS["dc_continuous"][0]}')
        else:
            add_result(name, version, 'PATCHED', f'Patched threshold: >= {THRESHOLDS["dc_continuous"][0]}')
        return

    if 'acrobat' in lname and 'dc' in lname:
        if cmp_ver(version, THRESHOLDS['dc_continuous'][0]) < 0:
            add_result(name, version, 'VULNERABLE', f'Patch level required: >= {THRESHOLDS["dc_continuous"][0]}')
        else:
            add_result(name, version, 'PATCHED', f'Patched threshold: >= {THRESHOLDS["dc_continuous"][0]}')
        return

    # Acrobat 2024 Classic
    if '2024' in lname and 'acrobat' in lname:
        if os_name == 'Windows':
            target = THRESHOLDS['acrobat_2024_windows'][0]
        else:
            target = THRESHOLDS['acrobat_2024_macos'][0]
        if cmp_ver(version, target) < 0:
            add_result(name, version, 'VULNERABLE', f'Patch level required: >= {target}')
        else:
            add_result(name, version, 'PATCHED', f'Patched threshold: >= {target}')
        return

    # Generic Adobe Reader/Acrobat install found but track unclear
    add_result(name, version, 'UNKNOWN', 'Adobe product found, but track could not be mapped confidently to CVE thresholds')


def scan_windows():
    try:
        import winreg
    except ImportError:
        add_result('Windows registry', None, 'UNKNOWN', 'winreg unavailable')
        return

    uninstall_roots = [
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'),
        (winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'),
    ]

    seen = set()

    def reg_get(key, value):
        try:
            return winreg.QueryValueEx(key, value)[0]
        except OSError:
            return None

    for hive, root in uninstall_roots:
        try:
            with winreg.OpenKey(hive, root) as kroot:
                for i in range(winreg.QueryInfoKey(kroot)[0]):
                    try:
                        subname = winreg.EnumKey(kroot, i)
                        with winreg.OpenKey(kroot, subname) as sk:
                            dn = reg_get(sk, 'DisplayName')
                            dv = reg_get(sk, 'DisplayVersion')
                            if not dn:
                                continue
                            ldn = str(dn).lower()
                            if 'adobe' in ldn and ('acrobat' in ldn or 'reader' in ldn):
                                ident = (dn, dv)
                                if ident in seen:
                                    continue
                                seen.add(ident)
                                assess_product(str(dn), str(dv) if dv else None, 'Windows')
                    except OSError:
                        continue
        except OSError:
            continue

    # Fallback known registry paths
    known_paths = [
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Adobe\Acrobat Reader\DC\Installer', 'Adobe Acrobat Reader DC'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Adobe\Adobe Acrobat\DC\Installer', 'Adobe Acrobat DC'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Adobe\Acrobat Reader\DC\Installer', 'Adobe Acrobat Reader DC'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Adobe\Adobe Acrobat\DC\Installer', 'Adobe Acrobat DC'),
    ]

    for hive, path, name in known_paths:
        try:
            with winreg.OpenKey(hive, path) as k:
                for val in ('ProductVersion', 'Version', 'AcroVersion'):
                    v = reg_get(k, val)
                    if v:
                        ident = (name, v)
                        if ident not in seen:
                            seen.add(ident)
                            assess_product(name, str(v), 'Windows')
                        break
        except OSError:
            continue


def mac_read_plist_value(app_path):
    plist = Path(app_path) / 'Contents' / 'Info.plist'
    if not plist.exists():
        return None
    try:
        import plistlib
        with open(plist, 'rb') as f:
            data = plistlib.load(f)
        return data.get('CFBundleShortVersionString') or data.get('CFBundleVersion')
    except Exception:
        return None


def scan_macos():
    app_candidates = [
        '/Applications/Adobe Acrobat Reader.app',
        '/Applications/Adobe Acrobat.app',
        '/Applications/Adobe Acrobat DC/Adobe Acrobat.app',
        '/Applications/Adobe Acrobat Reader DC.app',
    ]

    found_any = False

    for app in app_candidates:
        if Path(app).exists():
            found_any = True
            version = mac_read_plist_value(app)
            name = Path(app).stem
            assess_product(name, version, 'macOS')

    # Try Spotlight metadata as a fallback if available
    if not found_any:
        try:
            cmd = ['mdfind', 'kMDItemCFBundleIdentifier == "com.adobe.Reader" || kMDItemCFBundleIdentifier == "com.adobe.Acrobat.Pro"']
            out = subprocess.check_output(cmd, text=True, stderr=subprocess.DEVNULL)
            for line in [x.strip() for x in out.splitlines() if x.strip()]:
                version = mac_read_plist_value(line)
                name = Path(line).stem
                assess_product(name, version, 'macOS')
                found_any = True
        except Exception:
            pass

    if not found_any:
        add_result('Adobe Acrobat/Reader', None, 'UNKNOWN', 'No known Acrobat/Reader app bundle found')


def main():
    os_name = platform.system()
    if os_name == 'Windows':
        scan_windows()
    elif os_name == 'Darwin':
        scan_macos()
    else:
        print('UNKNOWN - Unsupported OS for this check')
        sys.exit(2)

    if not RESULTS:
        print('UNKNOWN - No Adobe Acrobat/Reader installation data found')
        sys.exit(2)

    for r in RESULTS:
        print(f"{r['status']}: {r['product']} {r['version']} ({r['note']})")

    statuses = {r['status'] for r in RESULTS}
    if 'VULNERABLE' in statuses:
        print('VULNERABLE')
        sys.exit(1)
    if 'PATCHED' in statuses and statuses.issubset({'PATCHED'}):
        print('PATCHED')
        sys.exit(0)

    print('UNKNOWN')
    sys.exit(2)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat this as an emergency endpoint patching problem, not a perimeter one: identify every Windows and macOS host running vulnerable Acrobat/Reader, isolate the highest-risk user groups that open outside PDFs, and patch / mitigate immediately, within hours because there is active exploitation and KEV listing. Under the noisgate mitigation SLA, your temporary controls should be in place immediately, within hours; under the noisgate remediation SLA, finish the vendor update rollout no later than 180 days, but in practice this one belongs in the first available emergency client-update wave, not the normal quarterly desktop cycle.

Sources

  1. Adobe APSB26-43 security bulletin
  2. NVD CVE-2026-34621
  3. CISA Known Exploited Vulnerabilities Catalog
  4. CVE.org record
  5. FIRST EPSS data and statistics
  6. OpenCVE record mirror
  7. Feedly exploit index for CVE-2026-34621
  8. CIRCL vulnerability lookup mirror
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.