{"id":"GHSA-jrmc-qg6p-94fp","summary":"veraPDF Parser DoS via PostScript CMap Streams","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'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).\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.","aliases":["CVE-2026-54080"],"modified":"2026-07-29T15:41:43.100891Z","published":"2026-07-29T15:17:32Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-07-29T15:17:32Z","nvd_published_at":null,"cwe_ids":["CWE-1325"],"severity":"MODERATE"},"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"}],"affected":[{"package":{"name":"org.verapdf:parser","ecosystem":"Maven","purl":"pkg:maven/org.verapdf/parser"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.30.2"}]}],"versions":["1.10.1","1.10.2","1.10.3","1.10.4","1.12.1","1.14.1","1.14.1-RC","1.14.10-RC","1.14.100","1.14.101","1.14.102","1.14.103","1.14.104","1.14.11-RC","1.14.2-RC","1.14.3-RC","1.14.4-RC","1.14.5-RC","1.14.6-RC","1.14.7-RC","1.14.9-RC","1.16.1","1.18.1","1.18.2","1.20.1","1.22.1","1.24.1","1.26.1","1.28.1","1.28.2","1.30.1","1.4.1","1.4.2","1.4.3","1.6.1","1.8.1"],"database_specific":{"last_known_affected_version_range":"\u003c= 1.30.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-jrmc-qg6p-94fp/GHSA-jrmc-qg6p-94fp.json"}},{"package":{"name":"org.verapdf:parser","ecosystem":"Maven","purl":"pkg:maven/org.verapdf/parser"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.31.1"},{"fixed":"1.31.23"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 1.31.22","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-jrmc-qg6p-94fp/GHSA-jrmc-qg6p-94fp.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","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"}]}