CVE-2026-107378
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
CVE-2026-107378- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
EUVDEUVD-2026-95135
8.7
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
EUVD-2026-95135- CVSS 4.0
- 8.7 High
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-c3jg-qh8m-j3h2
8.7
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
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:
- Tokenizer — the path-data parser consumes the
dstring with awhile string:loop that repeatedly slices/re-scans the remaining string (each step is O(len remaining)), giving O(n²) over the whole attribute. - draw_markers — marker handling drains
node.verticeswithwhile 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)
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.
- Record
GHSA-c3jg-qh8m-j3h2- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
NVD
8.7
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
CVE-2026-107378- CVSS 4.0
- 8.7 High
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-407
- Updated
- 2026-11-02
OSV
8.7
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
CVE-2026-107378- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-107378
8.7
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
DEBIAN-CVE-2026-107378- CVSS 4.0
- 8.7 High
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-03
Show 7 moreShow less
OSVGHSA-c3jg-qh8m-j3h2
8.7
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
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:
- Tokenizer — the path-data parser consumes the
dstring with awhile string:loop that repeatedly slices/re-scans the remaining string (each step is O(len remaining)), giving O(n²) over the whole attribute. - draw_markers — marker handling drains
node.verticeswithwhile 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)
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.
- Record
GHSA-c3jg-qh8m-j3h2- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
OSVPYSEC-2026-4204
8.7
CairoSVG: Quadratic-time DoS parsing a crafted SVG <path>
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:
- Tokenizer — the path-data parser consumes the
dstring with awhile string:loop that repeatedly slices/re-scans the remaining string (each step is O(len remaining)), giving O(n²) over the whole attribute. - draw_markers — marker handling drains
node.verticeswithwhile 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)
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.
- Record
PYSEC-2026-4204- CVSS 4.0
- 8.7 High
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 - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-107378
8.7
CairoSVG is an SVG converter based on Cairo, a 2D graphics library. Prior to 2.9.1, rendering an attacker-controlled SVG with a path containing many segments can cause quadratic CPU consumption in cairosvg/path.py. The path tokenizer repeatedly slices and rescans the remaining path data, while draw_markers drains node.vertices with node.vertices.pop(0), causing repeated linear-time work. The svg2png, svg2pdf, and svg2ps APIs reach these operations during ordinary rendering, allowing a sub-megabyte SVG to consume substantial CPU and deny service to a rendering application. This issue is fixed in version 2.9.1.
- Record
UBUNTU-CVE-2026-107378- CVSS 4.0
- 8.7 High
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 - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12111-1 No score
python313-CairoSVG-2.9.1-1.1 on GA media
These are all security issues fixed in the python313-CairoSVG-2.9.1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12111-1- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:22182-1 No score
Security update for python-CairoSVG
This update for python-CairoSVG fixes the following issue:
- CVE-2026-107378: rendering an attacker-controlled SVG with a path containing many segments can lead to quadratic CPU consumption (bsc#1284832).
- Record
openSUSE-SU-2026:22182-1- Updated
- 2026-11-02
OSVROOT-APP-PYPI-CVE-2026-107378 No score
CVE-2026-107378 in cairosvg - Patched by Root
Root has patched CVE-2026-107378 in the cairosvg package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-107378- Updated
- 2026-11-02
OSVSUSE-SU-2026:4949-1 No score
Security update for python-CairoSVG
This update for python-CairoSVG fixes the following issue:
- CVE-2026-107378: rendering an attacker-controlled SVG with a path containing many segments can lead to quadratic CPU consumption (bsc#1284832).
- Record
SUSE-SU-2026:4949-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
cairosvgPyPI |
through 2.9.0 | 2.9.1 |
cairosvgDebian:12 |
All versions, plus listed versions 2.5.2-1.12.5.2-1.1+deb12u12.7.0-12.7.1-12.7.1-2 Show 5 moreShow less2.8.2-12.9.0-12.9.0-22.9.1-12.9.1-2 |
None known |
cairosvgDebian:13 |
All versions, plus listed versions 2.7.1-22.8.2-12.9.0-12.9.0-22.9.1-12.9.1-2 |
None known |
cairosvgDebian:14 |
before 2.9.1-1, plus listed versions 2.7.1-22.8.2-12.9.0-12.9.0-2 |
2.9.1-1 |
cairosvgPyPI |
before 2.9.1, plus listed versions 0.10.1.10.1.20.20.3 Show 45 moreShow less0.3.10.40.4.10.4.20.4.30.4.40.51.01.0.11.0.101.0.111.0.121.0.131.0.141.0.151.0.161.0.171.0.181.0.191.0.21.0.201.0.211.0.221.0.31.0.41.0.51.0.61.0.71.0.81.0.92.0.02.0.0rc12.0.0rc22.0.0rc32.0.0rc42.0.0rc52.0.0rc62.0.12.0.22.0.32.1.02.1.12.1.22.1.32.2.0 |
2.9.1 |
cairosvgRoot:PyPI |
before 2.7.1+aikido.6 | 2.7.1+aikido.62.7.1+aikido.7 |
python-CairoSVGSUSE:Linux Enterprise Module for Python 3 15 SP7 |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
Show 14 moreShow less
| Package | Affected | Fixed |
|---|---|---|
python-CairoSVGSUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server 15 SP4-LTSS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server 15 SP5-LTSS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server 15 SP6-LTSS |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server for SAP Applications 15 SP4 |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server for SAP Applications 15 SP5 |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
python-CairoSVGSUSE:Linux Enterprise Server for SAP Applications 15 SP6 |
before 2.7.1-150400.9.9.1 | 2.7.1-150400.9.9.1 |
cairosvgUbuntu:16.04:LTS |
All versions, plus listed versions 1.0.16-11.0.17-11.0.19-1 |
None known |
cairosvgUbuntu:18.04:LTS |
All versions, plus listed versions 1.0.20-1 |
None known |
cairosvgUbuntu:20.04:LTS |
All versions, plus listed versions 2.4.0-22.4.2-1 |
None known |
cairosvgUbuntu:22.04:LTS |
All versions, plus listed versions 2.5.0-1.12.5.2-1 |
None known |
cairosvgUbuntu:24.04:LTS |
All versions, plus listed versions 2.7.1-1 |
None known |
python-CairoSVGopenSUSE:Tumbleweed |
before 2.9.1-1.1 | 2.9.1-1.1 |
python-CairoSVGopenSUSE:Leap 16.0 |
before 2.7.1-160000.4.1 | 2.7.1-160000.4.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107378 is a high vulnerability (CVSS 8.7) in Kozea Cairosvg, published October 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.38%, the 32nd percentile. Fixed in cairosvg 2.9.1.
References
github.com/Kozea/CairoSVG/security/advisories/GHSA-c3jg-qh8m-j3h2
github.com/Kozea/CairoSVG/commit/9d63f049f9988d0ddda3eb94564ac3a50a286523
github.com/Kozea/CairoSVG/commit/a4d585eb374724b79676e9cceaa9e9a1a4358565
github.com/Kozea/CairoSVG/releases/tag/2.9.1
nvd.nist.gov/vuln/detail/CVE-2026-107378
github.com/advisories/GHSA-c3jg-qh8m-j3h2
Show 9 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107378.json
security-tracker.debian.org/tracker/CVE-2026-107378
github.com/Kozea/CairoSVG
pypi.org/project/cairosvg
suse.com/support/update/announcement/2026/suse-su-20264949-1
bugzilla.suse.com/1284832
suse.com/security/cve/CVE-2026-107378
ubuntu.com/security/CVE-2026-107378
cve.org/CVERecord?id=CVE-2026-107378
Left out here: 16 versions. The JSON record has them.