GHSA-rw7v-4hrq-x6r9
fpdf2 implicitly loads external URLs and local image paths when rendering attacker-controlled content
Packages
Details
As written in the advisory (Markdown source, shown as plain text).
## Summary
`fpdf2` implicitly dereferences image resource references supplied to rendering APIs. If an application passes untrusted HTML, SVG, template data, or image paths into those APIs, `fpdf2` may issue outbound HTTP(S) requests or attempt to open local filesystem paths.
This behavior is relevant in applications that render untrusted or user-provided input without sanitizing or restricting embedded resource references.
## Description
In affected versions, `fpdf2` uses a shared internal image-loading mechanism for multiple features. This loader:
* fetches `http://` and `https://` URLs over the network
* opens other string values as local filesystem paths
During document processing, resource references embedded in input content are automatically dereferenced using this mechanism.
This behavior is reachable through:
* `FPDF.image()`
* `FPDF.write_html()` via HTML `<img src="...">`
* `FPDF.image()` when rendering SVG files containing `<image href="...">` or `xlink:href="...">`
* template image elements that forward values into `FPDF.image()`
If an application renders attacker-controlled input through these APIs, that input can cause:
* outbound HTTP(S) requests to attacker-chosen destinations
* local file open attempts for attacker-chosen paths
This may enable Server-Side Request Forgery (SSRF) in applications that render untrusted content.
Local file access impact is limited: the library attempts to open the referenced path, but successful embedding depends on the target being a valid and supported image or SVG resource.
`file://` URLs are not specially handled; raw filesystem paths such as `/path/to/file` or `../../file.png` are the relevant local-path cases.
## Impact
This issue affects applications that render untrusted or partially trusted content using `fpdf2`.
Applications may be impacted if they:
* pass untrusted HTML into `write_html()`
* render untrusted SVG with embedded `<image>` references
* pass user-controlled strings into `image()`
* allow untrusted template definitions or template field values to control image paths
Potential impacts include:
* outbound requests to internal or external network services
* limited local file access attempts depending on file type and parsing success (limited to content that fpdf2 recognizes as a supported image or SVG resource)
The severity depends on how `fpdf2` is integrated and whether untrusted input is allowed to control resource references.
**Example scenarios**
HTML:
```python
pdf.write_html('<img src="http://127.0.0.1:8000/internal.png">')
```
SVG:
```xml
<image href="http://169.254.169.254/latest/meta-data/" />
```
Direct image path:
```python
pdf.image("../../.env")
```
**Workarounds**
Applications can mitigate this by:
- not rendering untrusted HTML, SVG, or template content
- rejecting user-controlled `src` / `href` / image-path values
- mapping resources through an application-defined allowlist
- converting user-supplied images to trusted in-memory objects before passing them to `fpdf2`
**Credits**
- @kule500 for identifying SSRF via HTML <img> handling
- @BudongJW for identifying SVG <image> resource loading as an additional vector
- @redyank for analysis of the shared image loading mechanism
- @manop55555 for identifying a DNS rebinding bypass in the initial REMOTE_PUBLIC implementation
References
External links from the advisory. They lead to third-party sites.
- https://github.com/py-pdf/fpdf2/security/advisories/GHSA-rw7v-4hrq-x6r9
- https://nvd.nist.gov/vuln/detail/CVE-2026-114609
- https://github.com/py-pdf/fpdf2/pull/1824
- https://github.com/py-pdf/fpdf2/pull/1857
- https://github.com/py-pdf/fpdf2/commit/0d27190a8c907e02ebe9cd881471a14d0622b432
- https://github.com/py-pdf/fpdf2/commit/6e23f610b7946e96e9a5dd0535dcbfbe7ac1397d
- https://github.com/py-pdf/fpdf2
- https://github.com/py-pdf/fpdf2/releases/tag/2.8.8