Reflected cross-site scripting (XSS) In dompurify
Description
DOMPurify XSS via selectedcontent re-clone
Summary
DOMPurify 3.4.4 allows selectedcontent by default, allowing a chain in which browsers "re-clone" an XSS payload after sanitization, effectively bypassing DOMPurify.
Details
The chain is as follows:
The browser parses the input and creates a <selectedcontent> clone from the selected <option>
DOMPurify walks and sanitizes that generated clone.
DOMPurify reaches the original <option> and removes selected=javascript:1
The browser refreshes the <selectedcontent> clone from the original option's content.
The refreshed clone is in a subtree DOMPurify already walked, which DOMPurify doesn't go back to sanitize
The returned string contains unsanitized markup inside <selectedcontent>.
PoC
const dirty = '<select><button><selectedcontent></selectedcontent></button>' + '<option selected=javascript:1>' + '<img src=x onerror=alert(1)>x' + '</option></select>'; const clean = DOMPurify.sanitize(dirty); console.log(clean);...
Observed "sanitized" output in Chromium 148/WebKit 625:
<select><button><selectedcontent><img src="x" onerror="alert(1)">x</selectedcontent></button><option><img src="x">x</option></select>
After reinsertion, the browser updates the live DOM and strips the handler from the displayed clone, but the onerror has already fired:
<select><button><selectedcontent><img src="x">x</selectedcontent></button><option><img src="x">x</option></select>
Reproduced in Chromium and WebKit, but not Safari (not yet latest WebKit) or Firefox. Will likely change with browser support for selectedcontent.
Impact
This is a default-configuration DOMPurify sanitizer bypass resulting in XSS.
Applications are impacted if they sanitize attacker-controlled HTML with DOMPurify 3.4.4 using the string-input path and then insert the returned string into the page, for example with innerHTML.
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Package | Affected version | Patched versions |
|---|---|---|---|
npm | 3.4.5 |
Aliases
References