Files
vuln-osv/data/PyPI/GHSA-c3jg-qh8m-j3h2.json

1 line
3.6 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"schema_version":"1.9.0","id":"GHSA-c3jg-qh8m-j3h2","published":"2026-10-08T19:41:22Z","modified":"2026-10-15T14:56:21.119947482Z","aliases":["CVE-2026-107378","PYSEC-2026-4204"],"summary":"CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>","details":"## Summary\n\nRendering 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`:\n\n1. **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.\n2. **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²).\n\nBoth are hit on a normal render path (`svg2png`/`svg2pdf`), attacker controls only the SVG document.\n\n## PoC (installed cairosvg 2.9.0)\n\n```python\nimport cairosvg\nd = \"M0 0 \" + \"L1 1 \" * 100000\nsvg = f'<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\"><path d=\"{d}\"/></svg>'\ncairosvg.svg2png(bytestring=svg.encode()) # ~4.4 s for a 488 KB doc\n```\n\n| path segments | SVG size | time |\n|---|---|---|\n| 50,000 | 244 KB | 1.14 s |\n| 100,000 | 488 KB | 4.36 s |\n| 200,000 | ~960 KB | ~18 s |\n\nDoubling segments ≈ 4× time ⇒ quadratic. Sub-MiB input ⇒ ~18 s CPU; any service rendering user-supplied SVG (thumbnails, avatars, PDF export) is a DoS target.\n\n## Reachability\n\nPublic API `svg2png` / `svg2pdf` / `svg2ps` on an untrusted SVG string.\n\n## Suggested fix\n\nTokenize 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.","affected":[{"package":{"name":"cairosvg","ecosystem":"PyPI","purl":"pkg:pypi/cairosvg"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.9.1"}]}],"versions":["0.1","0.1.1","0.1.2","0.2","0.3","0.3.1","0.4","0.4.1","0.4.2","0.4.3","0.4.4","0.5","1.0","1.0.1","1.0.10","1.0.11","1.0.12","1.0.13","1.0.14","1.0.15","1.0.16","1.0.17","1.0.18","1.0.19","1.0.2","1.0.20","1.0.21","1.0.22","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.0.8","1.0.9","2.0.0","2.0.0rc1","2.0.0rc2","2.0.0rc3","2.0.0rc4","2.0.0rc5","2.0.0rc6","2.0.1","2.0.2","2.0.3","2.1.0","2.1.1","2.1.2","2.1.3","2.2.0","2.2.1","2.3.0","2.3.1","2.4.0","2.4.1","2.4.2","2.5.0","2.5.1","2.5.2","2.6.0","2.7.0","2.7.1","2.8.0","2.8.1","2.8.2","2.9.0"],"database_specific":{"last_known_affected_version_range":"<= 2.9.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-c3jg-qh8m-j3h2/GHSA-c3jg-qh8m-j3h2.json"}}],"references":[{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/security/advisories/GHSA-c3jg-qh8m-j3h2"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107378"},{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/commit/9d63f049f9988d0ddda3eb94564ac3a50a286523"},{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/commit/a4d585eb374724b79676e9cceaa9e9a1a4358565"},{"type":"PACKAGE","url":"https://github.com/Kozea/CairoSVG"},{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/releases/tag/2.9.1"}],"database_specific":{"cwe_ids":["CWE-407"],"github_reviewed":true,"github_reviewed_at":"2026-10-08T19:41:22Z","nvd_published_at":"2026-10-08T18:17:23Z","severity":"HIGH"},"severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"}]}