GHSA-JRMC-QG6P-94FP

Vulnerability from github – Published: 2026-07-29 15:17 – Updated: 2026-07-29 15:17
VLAI
Summary
veraPDF Parser DoS via PostScript CMap Streams
Details

Summary

Description

A PostScript-interpreter-driven Denial of Service (CWE-1325) vulnerability in veraPDF allows a remote attacker to exhaust validator memory or CPU by submitting a PDF whose Type 0 font /Encoding (or any /ToUnicode) is a CMap stream containing attacker-supplied PostScript. veraPDF reuses its CMap parser as a general PostScript interpreter and exposes the unguarded array N allocation operator and the for control operator with no zero-increment guard. This affects all current versions of veraPDF-parser.

Details

The vulnerability resides in veraPDF-parser. CMap streams referenced as a Type 0 font's /Encoding (or any font's /ToUnicode) are parsed by CMapParser (veraPDF-parser/src/main/java/org/verapdf/pd/font/cmap/CMapParser.java), which extends PSParser. Tokens that are not the small CMap-specific keyword set (begincodespacerange, bfchar, cidchar, ...) fall through to PSObject.execute (veraPDF-parser/src/main/java/org/verapdf/parser/postscript/PSObject.java), which dispatches generic PostScript operators implemented in PSOperator (veraPDF-parser/src/main/java/org/verapdf/parser/postscript/PSOperator.java).

Two operators in that interpreter take their bound from the PDF and apply no validation: 1. array at PSOperator.java:536-547 pops the top number from the operand stack and immediately calls COSArray.construct(arraySize), then loops arraySize times appending COSObject.getEmpty(). COSArray.construct(int) calls new ArrayList<>(arraySize) (COSArray.java:102), so the underlying Object[] is allocated up-front. Passing 2147483647 (Integer.MAX_VALUE) requests a 16 GB backing array on a 64-bit JVM. 2. for at PSOperator.java:571-592 reads initial, increment, and limit from the stack and loops for (long i = initial; i <= limit; i += increment). Because increment is unchecked, 0 0 1 { } for produces an infinite-CPU spin (and progressively a heap exhaustion as each iteration pushes i onto the operand stack).

CMapFactory.getCMap only catches IOException and PostScriptException; it does not catch OutOfMemoryError or wall-clock budget, so the failure propagates out of font model construction and aborts the validation worker.

A single payload byte sequence, the unframed PostScript 2147483647 array, is sufficient. No begincmap/endcmap framing is required because the operator runs before the parser ever reaches the CMap structure.

Impact

This impacts all current releases of the veraPDF-parser. Successful exploitation requires only that the target validate an attacker-supplied PDF; a single Type 0 font with a malicious /Encoding (or any /ToUnicode) stream is sufficient.

Proposed Patch

Cap array allocation and forbid zero increments in for.

As a defensive measure, also wrap CMapFactory.getCMap to enforce a wall-clock and operand-stack-size budget on CMap parsing, and audit the remaining unbounded operators (copy, roll, dict) for similar primitives.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.30.1"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.verapdf:parser"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.30.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.31.22"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.verapdf:parser"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.31.1"
            },
            {
              "fixed": "1.31.23"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54080"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1325"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-29T15:17:32Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Summary\n\n**Description**\n\nA PostScript-interpreter-driven Denial of Service (CWE-1325) vulnerability in veraPDF allows a remote attacker to exhaust validator memory or CPU by submitting a PDF whose Type 0 font `/Encoding` (or any `/ToUnicode`) is a CMap stream containing attacker-supplied PostScript. veraPDF reuses its CMap parser as a general PostScript interpreter and exposes the unguarded `array N` allocation operator and the `for` control operator with no zero-increment guard. This affects all current versions of veraPDF-parser.\n\n## Details\n\nThe vulnerability resides in veraPDF-parser. CMap streams referenced as a Type 0 font\u0027s `/Encoding` (or any font\u0027s `/ToUnicode`) are parsed by `CMapParser` (veraPDF-parser/src/main/java/org/verapdf/pd/font/cmap/CMapParser.java), which extends `PSParser`. Tokens that are not the small CMap-specific keyword set (`begincodespacerange`, `bfchar`, `cidchar`, ...) fall through to `PSObject.execute` (veraPDF-parser/src/main/java/org/verapdf/parser/postscript/PSObject.java), which dispatches generic PostScript operators implemented in `PSOperator` (veraPDF-parser/src/main/java/org/verapdf/parser/postscript/PSOperator.java).\n\nTwo operators in that interpreter take their bound from the PDF and apply no validation:\n1. `array` at PSOperator.java:536-547 pops the top number from the operand stack and immediately calls `COSArray.construct(arraySize)`, then loops `arraySize` times appending `COSObject.getEmpty()`. `COSArray.construct(int)` calls `new ArrayList\u003c\u003e(arraySize)` (COSArray.java:102), so the underlying `Object[]` is allocated up-front. Passing `2147483647` (`Integer.MAX_VALUE`) requests a 16 GB backing array on a 64-bit JVM.\n2. `for` at PSOperator.java:571-592 reads `initial`, `increment`, and `limit` from the stack and loops `for (long i = initial; i \u003c= limit; i += increment)`. Because `increment` is unchecked, `0 0 1 { } for` produces an infinite-CPU spin (and progressively a heap exhaustion as each iteration pushes `i` onto the operand stack).\n\n`CMapFactory.getCMap` only catches `IOException` and `PostScriptException`; it does not catch `OutOfMemoryError` or wall-clock budget, so the failure propagates out of font model construction and aborts the validation worker.\n\nA single payload byte sequence, the unframed PostScript `2147483647 array`, is sufficient. No `begincmap`/`endcmap` framing is required because the operator runs before the parser ever reaches the CMap structure.\n\n## Impact\n\nThis impacts all current releases of the veraPDF-parser. Successful exploitation requires only that the target validate an attacker-supplied PDF; a single Type 0 font with a malicious `/Encoding` (or any `/ToUnicode`) stream is sufficient.\n\n## Proposed Patch\n\nCap `array` allocation and forbid zero increments in `for`.\n\nAs a defensive measure, also wrap `CMapFactory.getCMap` to enforce a wall-clock and operand-stack-size budget on CMap parsing, and audit the remaining unbounded operators (`copy`, `roll`, `dict`) for similar primitives.",
  "id": "GHSA-jrmc-qg6p-94fp",
  "modified": "2026-07-29T15:17:32Z",
  "published": "2026-07-29T15:17:32Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/veraPDF/veraPDF-parser/security/advisories/GHSA-jrmc-qg6p-94fp"
    },
    {
      "type": "WEB",
      "url": "https://github.com/veraPDF/veraPDF-parser/pull/703"
    },
    {
      "type": "WEB",
      "url": "https://github.com/veraPDF/veraPDF-parser/commit/73d6ec002b98ce1f3f68640442f8e5d5613c80ce"
    },
    {
      "type": "WEB",
      "url": "https://github.com/veraPDF/veraPDF-parser/commit/cb3538607a549d63504299be1088c85ae48605f4"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/veraPDF/veraPDF-parser"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "veraPDF Parser DoS via PostScript CMap Streams"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…