GHSA-7J2X-32W6-P43P
Vulnerability from github – Published: 2026-03-20 20:35 – Updated: 2026-03-25 20:53Summary
The ensureSize() function in @dicebear/converter used a regex-based approach to rewrite SVG width/height attributes, capping them at 2048px to prevent denial of service. This size capping could be bypassed by crafting SVG input that causes the regex to match a non-functional occurrence of <svg before the actual SVG root element. When the SVG is subsequently rendered via @resvg/resvg-js on the Node.js code path, it renders at the attacker-specified dimensions, potentially causing out-of-memory crashes.
Details
The vulnerable function used String.prototype.replace() with a non-global regex to find and rewrite the first <svg tag's dimensions. Since the regex does not distinguish between <svg appearing inside non-element XML constructs and the actual SVG root element, a crafted input can cause the regex to match a decoy instead of the real element, leaving the actual SVG dimensions unclamped.
In the Node.js rendering path, renderAsync from @resvg/resvg-js was called without a fitTo constraint, so it would render at whatever dimensions the SVG element specified — potentially allocating gigabytes of memory.
The browser code path is not vulnerable because it uses the clamped size return value from ensureSize() to set canvas.width and canvas.height directly.
Impact
Any application that passes untrusted or user-supplied SVG content through @dicebear/converter's Node.js conversion functions (toPng, toJpeg, toWebp, toAvif) is vulnerable to denial of service via excessive memory allocation. Note that @dicebear/converter can be used independently of DiceBear's avatar generation — any SVG string can be passed to the conversion functions.
The impact is limited to availability — there is no data disclosure or integrity impact. The browser code path is not affected.
Fix
The regex-based approach has been replaced with XML-aware processing using fast-xml-parser to correctly identify and modify the SVG root element's attributes. Additionally, a fitTo constraint has been added to the renderAsync call as defense-in-depth, ensuring the rendered output is always bounded regardless of SVG content.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.4.1"
},
"package": {
"ecosystem": "npm",
"name": "@dicebear/converter"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "9.4.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33418"
],
"database_specific": {
"cwe_ids": [
"CWE-185"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-20T20:35:40Z",
"nvd_published_at": "2026-03-24T14:16:30Z",
"severity": "HIGH"
},
"details": "## Summary\n\nThe `ensureSize()` function in `@dicebear/converter` used a regex-based approach to rewrite SVG `width`/`height` attributes, capping them at 2048px to prevent denial of service. This size capping could be bypassed by crafting SVG input that causes the regex to match a non-functional occurrence of `\u003csvg` before the actual SVG root element. When the SVG is subsequently rendered via `@resvg/resvg-js` on the Node.js code path, it renders at the attacker-specified dimensions, potentially causing out-of-memory crashes.\n\n## Details\n\nThe vulnerable function used `String.prototype.replace()` with a non-global regex to find and rewrite the first `\u003csvg` tag\u0027s dimensions. Since the regex does not distinguish between `\u003csvg` appearing inside non-element XML constructs and the actual SVG root element, a crafted input can cause the regex to match a decoy instead of the real element, leaving the actual SVG dimensions unclamped.\n\nIn the Node.js rendering path, `renderAsync` from `@resvg/resvg-js` was called without a `fitTo` constraint, so it would render at whatever dimensions the SVG element specified \u2014 potentially allocating gigabytes of memory.\n\nThe browser code path is **not** vulnerable because it uses the clamped `size` return value from `ensureSize()` to set `canvas.width` and `canvas.height` directly.\n\n## Impact\n\nAny application that passes untrusted or user-supplied SVG content through `@dicebear/converter`\u0027s Node.js conversion functions (`toPng`, `toJpeg`, `toWebp`, `toAvif`) is vulnerable to denial of service via excessive memory allocation. Note that `@dicebear/converter` can be used independently of DiceBear\u0027s avatar generation \u2014 any SVG string can be passed to the conversion functions.\n\nThe impact is limited to availability \u2014 there is no data disclosure or integrity impact. The browser code path is not affected.\n\n## Fix\n\nThe regex-based approach has been replaced with XML-aware processing using `fast-xml-parser` to correctly identify and modify the SVG root element\u0027s attributes. Additionally, a `fitTo` constraint has been added to the `renderAsync` call as defense-in-depth, ensuring the rendered output is always bounded regardless of SVG content.",
"id": "GHSA-7j2x-32w6-p43p",
"modified": "2026-03-25T20:53:40Z",
"published": "2026-03-20T20:35:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dicebear/dicebear/security/advisories/GHSA-7j2x-32w6-p43p"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33418"
},
{
"type": "PACKAGE",
"url": "https://github.com/dicebear/dicebear"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "SVG Dimension Capping Bypass via XML Comment Injection in @dicebear/converter ensureSize()"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.