{"id":"GHSA-6fj4-rcr3-r7rr","kind":"vulnerability","aliases":["GHSA-6fj4-rcr3-r7rr"],"related":[],"title":"lopdf has a stack overflow via deeply nested PDF objects","description":"`lopdf::Document::load_mem` (and the other `load*` entry points) parses nested PDF arrays and dictionaries with unbounded recursion. A small crafted PDF whose Catalog contains a deeply nested array (`/X [[[ … ]]]`, on the order of 10,000 levels) exhausts the call stack and aborts the process with `SIGABRT`.\n\nBecause this is a stack-overflow abort rather than a `panic!`, it cannot be caught with `catch_unwind`: any service that parses untrusted PDF input with lopdf can be crashed by a ~21 KB file, resulting in a denial of service.\n\nConfirmed on lopdf 0.41.0 and earlier; fixed in 0.42.0. Default configuration, no features changed.\n\n## Proof of concept\n\n```rust\nfn main() {\n    let bytes = std::fs::read(\"poc.pdf\").unwrap(); // ~10,380-deep nested array in the Catalog\n    let _ = lopdf::Document::load_mem(&bytes);     // stack overflow -> SIGABRT\n}\n```\n\nAn equivalent PoC is a minimal PDF whose Catalog `/X` value is `\"[\" * 10380 + \"]\" * 10380`.\n\n## Suggested fix\n\nEnforce a maximum object-nesting depth in the parser and return an `Err` instead of recursing without bound.","summary":"lopdf, a Rust PDF library, recurses without a depth limit when parsing nested arrays and dictionaries, so a small crafted PDF with about 10,000 nesting levels overflows the stack. An attacker who can get a service to parse an untrusted PDF crashes the whole process with SIGABRT, which cannot be caught, causing denial of service.","severity":"high","cvss":7.5,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"lopdf","fixed":["0.42.0"],"affected":"< 0.42.0","ecosystem":"cargo"}],"ecosystems":["cargo"],"tags":["cargo","cwe-1124","lopdf","package","pdf-parsing","rust","untrusted-input"],"not_affected_if":["lopdf-below-vulnerable-range","no-untrusted-pdf-input"],"how_to_check":"Check Cargo.lock for lopdf: run `cargo tree -i lopdf` or `grep -A1 'name = \"lopdf\"' Cargo.lock` and look for a version below 0.42.0.","fix":"Upgrade lopdf to 0.42.0 or later.\nIf upgrading is not possible, reject or size-limit untrusted PDF input before calling lopdf::Document::load_mem or the other load* functions.","status":"open","published_at":"2026-10-16T19:55:39+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","triaged_at":"2026-10-23T19:55:44+00:00","updated_at":"2026-10-23T19:55:44+00:00","category":"package","confidence":0.9,"triage":{"at":"2026-10-23T19:55:44Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade lopdf to 0.42.0 or later.\nIf upgrading is not possible, reject or size-limit untrusted PDF input before calling lopdf::Document::load_mem or the other load* functions.","summary":"lopdf, a Rust PDF library, recurses without a depth limit when parsing nested arrays and dictionaries, so a small crafted PDF with about 10,000 nesting levels overflows the stack. An attacker who can get a service to parse an untrusted PDF crashes the whole process with SIGABRT, which cannot be caught, causing denial of service.","category":"package","who_cares":["rust","cargo","lopdf","pdf-parsing","untrusted-input"],"confidence":0.9,"analyst_note":"","how_to_check":"Check Cargo.lock for lopdf: run `cargo tree -i lopdf` or `grep -A1 'name = \"lopdf\"' Cargo.lock` and look for a version below 0.42.0.\nunknown","needs_analyst":false,"not_affected_if":["no-untrusted-pdf-input","lopdf-below-vulnerable-range"],"severity_if_unknown":"high"},"cost_usd":0.000442,"input_tokens":2408,"output_tokens":402,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-1124':24B '/x':120C,233C '0.41.0':183C '0.42.0':188C '000':58B,126C '10':57B,125C,207C '10380':236C,237C '21':171C '380':208C '6fj4':13A,18A 'abort':133C,145C 'array':47B,103C,119C,211C 'attack':65B 'bound':258C 'byte':201C,220C 'call':130C 'cannot':83B,151C 'cargo':22B 'catalog':114C,214C,232C 'catch':155C 'caught':85B,153C 'caus':86B 'chang':193C 'concept':196C 'configur':190C 'confirm':180C 'contain':115C 'craft':53B,111C 'crash':76B,168C 'cwe':23B 'deep':209C 'deepli':7A,117C 'default':189C 'denial':87B,177C 'depth':42B,246C 'dictionari':49B,105C 'document':91C,217C 'earlier':185C 'enforc':240C 'entri':98C 'equival':225C 'err':253C 'exhaust':128C 'featur':192C 'file':173C 'fix':186C,239C 'fn':198C 'fs':203C 'get':68B 'ghsa':12A,17A 'ghsa-6fj4-rcr3-r7rr':11A,16A 'input':33B,163C 'instead':254C 'kb':172C 'let':200C,215C 'level':60B,127C 'librari':38B 'limit':43B 'load':92C,97C,218C 'lopdf':1A,21A,25B,34B,90C,165C,182C,216C 'main':199C 'maximum':242C 'mem':93C,219C 'minim':229C 'nest':8A,46B,59B,101C,118C,210C,245C 'object':10A,244C 'object-nest':243C 'order':123C 'overflow':5A,61B,144C,222C 'packag':26B 'panic':149C 'pars':29B,45B,72B,100C,160C 'parser':249C 'pdf':9A,28B,37B,54B,75B,102C,112C,162C,230C 'pdf-pars':27B 'poc':226C 'poc.pdf':205C 'point':99C 'process':79B,135C 'proof':194C 'r7rr':15A,20A 'rather':146C 'rcr3':14A,19A 'read':204C 'recurs':39B,108C,256C 'result':174C 'return':251C 'rust':30B,36B,197C 'servic':70B,89B,158C,179C 'sigabrt':81B,137C,223C 'small':52B,110C 'stack':4A,63B,131C,143C,221C 'stack-overflow':142C 'std':202C 'suggest':238C 'unbound':107C 'untrust':32B,74B,161C 'untrusted-input':31B 'unwind':156C 'unwrap':206C 'valu':234C 'via':6A 'whole':78B 'whose':113C,231C 'without':40B,257C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-16T19:55:39+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-6fj4-rcr3-r7rr","url":"https://github.com/advisories/GHSA-6fj4-rcr3-r7rr","severity":"high","published_at":"2026-10-16T19:55:39+00:00","modified_at":"2026-10-16T19:55:40+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","fetched_at":"2026-10-23T19:11:32+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}