Findings

CVE-2026-107378

CairoSVG: Quadratic-time DoS parsing a crafted SVG

Published Oct 8, 2026 · updated Oct 15, 2026

## Summary Rendering an untrusted SVG whose contains many segments is O(n²) CPU. A single under 1 MiB burns tens of seconds. Two independent O(n²) sites in : 1. **Tokenizer** — the path-data parser consumes the string with a 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 with ; is O(n), so draining n vertices is O(n²). Both are hit on a normal render path ( / ), attacker controls only the SVG document. ## PoC (installed cairosvg 2.9.0) | 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 / / on an untrusted SVG string. ## Suggested fix Tokenize with a single forward scan / index (or ) instead of re-slicing the remainder; drain with an index or instead of . Optionally cap path-segment count.

Code

The project this record applies to. Exploit listings stay in References.

Timeline

Detection, updates, and resolution for this record.

  1. Oct 8, 2026 · GitHub Advisory Database

    Detected

    ## Summary Rendering an untrusted SVG whose contains many segments is O(n²) CPU. A single under 1 MiB burns tens of seconds. Two independent O(n²) sites in : 1. **Tokenizer** — the path-data parser consumes the string with a 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 drain

  2. Oct 15, 2026 · GitHub Advisory Database

    Fix available

    cairosvg fixed in 2.9.1

  3. Oct 15, 2026 · GitHub Advisory Database

    Fix available

    cairosvg fixed in 2.9.1

  4. Oct 15, 2026 · GitHub Advisory Database

    Updated

    ## Summary Rendering an untrusted SVG whose contains many segments is O(n²) CPU. A single under 1 MiB burns tens of seconds. Two independent O(n²) sites in : 1. **Tokenizer** — the path-data parser consumes the string with a 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 drain

Affected

  • PyPI cairosvg0 → 2.9.1

Sources

References