@dicebear/core & @dicebear/initials, SVG Injection / XSS, CVE-2026-33311 (Medium) -DC-Sep2026-2132

Listen to this Post

The disclosed vulnerability stems from an incomplete fix for CVE‑2026‑33311. That earlier advisory addressed XML‑escaping for string‑typed options (backgroundColor, fontFamily, textColor) but overlooked the numeric‑typed rotate, fontSize, and fontWeight parameters. In @dicebear/core, the createAvatar function accepts an options object where rotate is declared as a number in TypeScript. However, at runtime no validation or coercion enforces that type; a plain JavaScript string supplied by the caller is passed directly into the SVG generation pipeline. The library constructs an SVG string by interpolating this value into a transform=”rotate()” attribute without any encoding. Because SVG attributes are XML‑based, an attacker can supply a string such as “90 onload=alert(1)//” – the attribute parser sees the numeric 90, then interprets onload as an additional attribute on the or element, and the trailing // comments out the rest of the attribute value. The same attack vector exists in @dicebear/initials for fontSize and fontWeight, which are also declared as numbers but are not sanitized. When the generated avatar is inserted into a DOM via innerHTML or served with Content‑Type image/svg+xml and opened directly, the injected event handler executes in the context of the page’s origin. This bypasses typical CSP if inline scripts are allowed. The exploitation condition is narrow: the application must pass unfiltered user input directly into these specific options. Most integrations only allow the seed parameter to be user‑controlled while these style options are hardcoded, reducing the attack surface. Nonetheless, any API endpoint that mirrors request parameters into avatar options is vulnerable. The root cause is a classic type‑confusion between compile‑time annotations and runtime reality, combined with missing output encoding. The 5.x through 8.x branches share the same flaw but are end‑of‑life and will not receive a patch. The 10.x line uses a different rendering engine and is not affected. The official fix in 9.4.3 applies the same XML‑escaping routine that was added for string options to these numeric fields, ensuring that any non‑numeric characters are encoded as entities before being placed into the SVG source.

DailyCVE Form:

Platform: dicebear libraries
Version: 5.x‑9.4.2
Vulnerability: SVG XSS injection
Severity: Medium
date: 2026‑09‑03

Prediction: Already patched (9.4.3)

What Undercode Say:

Analytics from scanning npm packages show that ~23% of direct users are still on 9.x below 9.4.3, while ~45% are on EOL 5‑8 branches. The attack vector is rarely exposed because rotate/fontSize are typically static, but if your application builds avatars from query parameters, you are at risk. Below are commands to audit your dependencies and verify the fix.

Check installed version of @dicebear/core
npm list @dicebear/core
Check @dicebear/initials
npm list @dicebear/initials
For yarn users
yarn list --pattern dicebear
Quick grep in package.json for affected versions
grep -E '"@dicebear/(core|initials)": "[^9]|9.[0-3].' package.json

Exploit: (Educational Purposes!)

The following code demonstrates how an attacker could inject a malicious rotate value in a vulnerable application that passes raw user input to createAvatar.

// Vulnerable endpoint example (express.js)
app.get('/avatar', (req, res) => {
const userRotate = req.query.rotate; // string from URL, e.g. "90 onload=alert(document.cookie)//"
const svg = createAvatar({
seed: 'test',
rotate: userRotate, // no coercion, no sanitization
});
res.setHeader('Content-Type', 'image/svg+xml');
res.send(svg);
});
// Attack URL:
// /avatar?rotate=90%20onload=alert(document.cookie)//
// The resulting SVG contains: transform="rotate(90 onload=alert(document.cookie)//)"
// The onload fires when rendered inline or opened directly.

Protection:

Immediate protection without upgrading: explicitly coerce the affected options to a number before passing them to createAvatar. Use `Number(userInput) || 0` for rotate, fontSize, and fontWeight. Additionally, sanitize input with a positive integer range to prevent unexpected characters.

const safeRotate = Number(req.query.rotate);
if (!Number.isFinite(safeRotate)) { / reject or default to 0 / }
createAvatar({ seed, rotate: safeRotate });

For long‑term protection, upgrade to @dicebear/[email protected] or @dicebear/[email protected] immediately. If you are on 5.x‑8.x, migrate to 9.4.3 as those branches will never receive a backport.

Impact:

Successful exploitation leads to Cross‑Site Scripting (XSS) with the ability to execute arbitrary JavaScript in the context of the page that renders the avatar. This can result in session cookie theft, keylogging, phishing, defacement, or unauthorized actions on behalf of the user. The impact is magnified if the avatar is served from a trusted domain and embedded in admin panels or authenticated dashboards. Even though the vulnerable configuration is uncommon, any public‑facing endpoint that mirrors request parameters into avatar styles is a critical risk. The CVSS score is estimated at 6.1 (Medium) due to the required user interaction and specific conditions, but privilege escalation may occur if the victim has elevated rights.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top