---
id: "GHSA-6fj4-rcr3-r7rr"
kind: "vulnerability"
aliases: ["GHSA-6fj4-rcr3-r7rr"]
title: "lopdf has a stack overflow via deeply nested PDF objects"
severity: "high"
cvss: 7.5
epss: null
exploited: false
status: "open"
category: "package"
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"]
published_at: "2026-10-16T19:55:39+00:00"
first_seen_at: "2026-10-23T19:11:32+00:00"
updated_at: "2026-10-23T19:55:44+00:00"
sources: [{"source": "ghsa", "url": "https://github.com/advisories/GHSA-6fj4-rcr3-r7rr", "first_seen_at": "2026-10-23T19:11:32+00:00"}]
---

# lopdf has a stack overflow via deeply nested PDF objects

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.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- cargo:lopdf affected < 0.42.0 fixed 0.42.0

## 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.
If upgrading is not possible, reject or size-limit untrusted PDF input before calling lopdf::Document::load_mem or the other load* functions.

## Timeline

- 2026-10-23T19:11:32+00:00 ghsa https://github.com/advisories/GHSA-6fj4-rcr3-r7rr

## From the sources

`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`.

Because 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.

Confirmed on lopdf 0.41.0 and earlier; fixed in 0.42.0. Default configuration, no features changed.

## Proof of concept

```rust
fn main() {
    let bytes = std::fs::read("poc.pdf").unwrap(); // ~10,380-deep nested array in the Catalog
    let _ = lopdf::Document::load_mem(&bytes);     // stack overflow -> SIGABRT
}
```

An equivalent PoC is a minimal PDF whose Catalog `/X` value is `"[" * 10380 + "]" * 10380`.

## Suggested fix

Enforce a maximum object-nesting depth in the parser and return an `Err` instead of recursing without bound.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
