{"id":"GHSA-7c26-995w-6f47","summary":"veraPDF Parser DoS via PostScript Type 1 Font Programs","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 1 font `/FontFile` is a font program containing attacker-supplied PostScript. veraPDF's Type 1 font program parser dispatches every cleartext token through a hardcoded operator allow-list whose members include the unbounded `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. Type 1 font program streams referenced from any Type 1 font's `/FontDescriptor /FontFile` are parsed by `Type1FontProgram` (veraPDF-parser/src/main/java/org/verapdf/pd/font/type1/Type1FontProgram.java), which extends `PSParser`. `parseFont` reads cleartext PostScript tokens until it encounters `eexec` (which switches into the encrypted private dictionary parser) or end-of-stream. Each non-`eexec` token is dispatched via `toExecute`, which gates execution behind a hardcoded allow-list.\n\nThe allow-list explicitly admits both `ARRAY` (Type1FontProgram.java:98) and `FOR` (Type1FontProgram.java:100). When either keyword passes the gate, `operator.execute` delegates straight into the generic `PSOperator` implementation (`org.verapdf.parser.postscript.PSOperator`, methods `array()` at PSOperator.java:536-547 and `opFor()` at PSOperator.java:571-592), which apply no validation:\n\n1. `array N` calls `COSArray.construct(N)` followed by `new ArrayList\u003c\u003e(N)` (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` runs `for (long i = initial; i \u003c= limit; i += increment)` with no validation of `increment`. With `increment == 0`, the loop never exits.\n\nIn addition to the two shared primitives, `toExecute` introduces a third primitive specific to this code path: when an unknown operator is encountered, it looks the name up in `userDict` and recursively re-executes the value. There is no visited-set, no recursion-depth cap, and no detection of a cycle. A Type 1 font program that defines a name to itself, such as `/loop { loop } def loop`, recurses indefinitely on the JVM stack and throws `StackOverflowError` after ~16,000 frames.\n\nThe interpreter is reachable on every Type 1 font validation. `GFPDType1Font`'s constructor unconditionally calls `program.parseFont()`.\n\n`Type1FontProgram.parseFont` only catches `PostScriptException` and rewraps it as `IOException`; it does not catch `OutOfMemoryError`, `StackOverflowError`, or wall-clock budget, so any of the three failure modes propagates out of font model construction and aborts the validation worker.\n\nA single payload byte sequence is sufficient. The conventional `%!PS-AdobeFont-1.0` header line is treated as a comment and skipped; the parser then begins consuming PostScript tokens, the very first `for` invocation enters the infinite loop, and the parser never reaches the `eexec` boundary that would normally end the cleartext section.\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 1 font with a malicious `/FontFile` stream is sufficient.","aliases":["CVE-2026-54081"],"modified":"2026-07-29T15:42:33.458123Z","published":"2026-07-29T15:19:04Z","database_specific":{"cwe_ids":["CWE-1325"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-07-29T15:19:04Z","nvd_published_at":null},"references":[{"type":"WEB","url":"https://github.com/veraPDF/veraPDF-parser/security/advisories/GHSA-7c26-995w-6f47"},{"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":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-7c26-995w-6f47/GHSA-7c26-995w-6f47.json","last_known_affected_version_range":"\u003c= 1.30.1"}},{"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-7c26-995w-6f47/GHSA-7c26-995w-6f47.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"}]}