### Install isomorphic-dompurify Source: https://github.com/cure53/dompurify/blob/main/README.md Install the isomorphic-dompurify package to simplify server-side DOMPurify usage. ```bash npm install isomorphic-dompurify ``` -------------------------------- ### Install Server-Side Dependencies Source: https://github.com/cure53/dompurify/blob/main/README.md Install DOMPurify and jsdom for server-side usage with Node.js. Ensure you use an up-to-date version of jsdom. ```bash npm install dompurify npm install jsdom ``` -------------------------------- ### Namespace Confusion Payload Example 2 Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Another example illustrating namespace confusion, this time using SVG elements to embed potentially harmful HTML. ```html

``` -------------------------------- ### Verify TypeScript Integration Source: https://github.com/cure53/dompurify/blob/main/README.md Run the TypeScript verification script. This ensures that the project's TypeScript setup is correct and that type definitions are accurate. ```bash npm run verify-typescript ``` -------------------------------- ### Run Legacy Browser Tests Source: https://github.com/cure53/dompurify/blob/main/README.md Run the test suite on older browser engines. Point the PW_MODULE environment variable to a pinned old Playwright install. ```bash npm run test:browser:legacy ``` -------------------------------- ### MathML Annotation-XML Integration Point Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This example demonstrates a MathML annotation-xml element with an 'text/html' encoding, serving as an integration point for HTML content within MathML. ```html ... ``` -------------------------------- ### Namespace Confusion Payload Example 1 Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This payload demonstrates how elements from different namespaces can be nested, potentially leading to parsing confusion and XSS if not handled correctly. ```html DEF GHI ``` -------------------------------- ### Style Rawtext Breakout Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Shows a rawtext breakout within a style tag, where a closing style tag is embedded in an attribute selector, potentially leading to XSS. ```html "] {} ``` -------------------------------- ### HTML Anchor with JavaScript URI Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History A basic HTML example demonstrating a common attack vector using a JavaScript URI within an anchor tag's href attribute. ```html click ``` -------------------------------- ### Risky DOMPurify Usage Contracts Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History These examples illustrate common but risky ways to use sanitized output, highlighting contexts where DOMPurify's HTML sanitization may not be sufficient. ```javascript script.text = clean; // JavaScript context, not HTML ``` ```javascript element.setAttribute('title', clean); // Attribute context, not HTML ``` ```javascript svgElement.innerHTML = clean; // SVG/XML context mismatch ``` ```javascript templateEngine.render(clean); // Second interpreter after HTML ``` ```javascript someLibrary.html(clean); // Library may mutate or reparse ``` -------------------------------- ### SVG ForeignObject Integration Point Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This example shows an SVG foreignObject element, which acts as an integration point allowing HTML-like parsing within SVG. ```html ... ``` -------------------------------- ### DOMPurify Allow-list/Block-list Precedence Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Demonstrates how FORBID_* tags take precedence over ADD_* tags in DOMPurify configuration. This is crucial for ensuring that explicitly forbidden elements are always removed, regardless of allow-list rules. ```javascript DOMPurify.sanitize('', { ADD_TAGS: () => true, FORBID_TAGS: ['iframe'] }); ``` -------------------------------- ### Extend Forbidden Contents List Source: https://github.com/cure53/dompurify/blob/main/README.md Add to the default list of forbidden contents. This example extends the list to also remove `` elements under `

` elements. ```javascript // extend the default FORBID_CONTENTS list to also remove elements under

elements const clean = DOMPurify.sanitize(dirty, { ADD_FORBID_CONTENTS: ['a'], FORBID_TAGS: ['p'], }); ``` -------------------------------- ### DOMPurify Add and Remove Hooks Source: https://github.com/cure53/dompurify/blob/main/demos/README.md Shows how to add a hook to DOMPurify and subsequently remove it. The example adds a hook to uppercase text, sanitizes, removes the hook, and sanitizes again. ```javascript // Add a hook to convert all text to capitals DOMPurify.addHook('beforeSanitizeAttributes', function (node) { // Set text node content to uppercase if (node.nodeName && node.nodeName === '#text') { node.textContent = node.textContent.toUpperCase(); } }); // Clean HTML string and write into our DIV let clean = DOMPurify.sanitize(dirty); // now let's remove the hook again console.log(DOMPurify.removeHook('beforeSanitizeAttributes')); // Clean HTML string and write into our DIV let clean = DOMPurify.sanitize(dirty); ``` -------------------------------- ### Configure DOMPurify QUnit Test Suite Source: https://github.com/cure53/dompurify/blob/main/test/browser/index.html Disables QUnit's automatic test starting and sets a custom name for the DOMPurify test suite. Ensure QUnit is loaded before this script. ```javascript QUnit.config.autostart = false; window.__SUITE_NAME__ = 'DOMPurify src'; ``` -------------------------------- ### DOMPurify URI Scheme Confusion Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Illustrates a potential bypass where an attribute is configured to be safe for URIs (e.g., 'data-target'), but is later used in a way that can lead to navigation, bypassing sanitization checks. ```javascript DOMPurify.sanitize(dirty, { ALLOW_UNKNOWN_PROTOCOLS: true }); ``` ```javascript DOMPurify.sanitize(dirty, { ADD_URI_SAFE_ATTR: ['data-target'] }); ``` -------------------------------- ### Textarea Rawtext Breakout Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Illustrates a rawtext breakout within a textarea tag, similar to noscript, where a closing textarea tag is embedded in an attribute value, enabling XSS. ```html "> ``` -------------------------------- ### HTML Nesting Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Illustrates deep HTML nesting within an SVG element, repeated until the parser's nesting behavior changes. This can lead to elements being flattened as siblings rather than children. ```html ``` -------------------------------- ### HTML Structure for DOM Clobbering Example Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This HTML snippet illustrates a classic DOM clobbering primitive where a named element within a form can shadow properties on host objects like 'document'. ```html
``` -------------------------------- ### Custom Element Handling with RegExp Source: https://github.com/cure53/dompurify/blob/main/README.md This snippet demonstrates allowing custom elements and attributes using regular expressions. It permits tags starting with 'foo-' and attributes containing 'baz'. Customized built-in elements are also allowed. ```javascript const clean = DOMPurify.sanitize( '

', { CUSTOM_ELEMENT_HANDLING: { tagNameCheck: /^foo-/, // allow all tags starting with "foo-" attributeNameCheck: /baz/, // allow all attributes containing "baz" allowCustomizedBuiltInElements: true, // customized built-ins are allowed }, } ); //
``` -------------------------------- ### Initial Load and Fixture Loading Source: https://github.com/cure53/dompurify/blob/main/website/index.html Initializes the application by setting the DOMPurify version and loading the test fixtures upon page load. This ensures the demo is ready with sample data. ```javascript loadFixtures(); ``` -------------------------------- ### DOMPurify Initialization and Configuration Source: https://github.com/cure53/dompurify/blob/main/website/index.html Sets up DOMPurify for sanitization, including retrieving configuration based on a selected preset (e.g., 'html', 'strict', 'templates', 'trusted'). ```javascript function getConfig() { const selected = document.getElementById('preset').value; if (selected === 'html') return { USE_PROFILES: { html: true } }; if (selected === 'strict') return { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'], ALLOWED_ATTR: ['href', 'title'] }; if (selected === 'templates') return { SAFE_FOR_TEMPLATES: true }; if (selected === 'trusted') return { RETURN_TRUSTED_TYPE: true }; return {}; } ``` -------------------------------- ### Run Micro-benchmark Source: https://github.com/cure53/dompurify/blob/main/README.md Execute the jsdom micro-benchmark over the built dist/purify.cjs file. Build the project first. Supports A/B runs across branches using --json and --compare flags. ```bash npm run bench ``` -------------------------------- ### Forbid Specific Contents and Tags Source: https://github.com/cure53/dompurify/blob/main/README.md Remove specified elements and their contents. For example, remove all `
` elements under `

` elements. ```javascript // remove all elements under

elements that are removed const clean = DOMPurify.sanitize(dirty, { FORBID_CONTENTS: ['a'], FORBID_TAGS: ['p'], }); ``` -------------------------------- ### DOMPurify with Advanced Configuration Source: https://github.com/cure53/dompurify/blob/main/demos/README.md Illustrates advanced DOMPurify configuration, allowing custom tags ('ying', 'yang'), specific attributes ('kitty-litter'), and returning a DOM document instead of a string. ```javascript // Specify a configuration directive const config = { ALLOWED_TAGS: ['p', '#text'], // only

and text nodes KEEP_CONTENT: false, // remove content from non-allow-listed nodes too ADD_ATTR: ['kitty-litter'], // permit kitty-litter attributes ADD_TAGS: ['ying', 'yang'], // permit additional custom tags RETURN_DOM: true, // return a document object instead of a string }; // Clean HTML string and write into our DIV const clean = DOMPurify.sanitize(dirty, config); ``` -------------------------------- ### Build Instrumented Coverage Bundle Source: https://github.com/cure53/dompurify/blob/main/README.md Only build the instrumented bundle required for coverage analysis. This is a prerequisite for running the coverage report locally. ```bash npm run build:cov ``` -------------------------------- ### Configure QUnit Autostart Source: https://github.com/cure53/dompurify/blob/main/test/browser/index.min.html Disable autostart for QUnit tests to manually control test execution. Set the suite name for DOMPurify distribution tests. ```javascript QUnit.config.autostart = false; window.__SUITE_NAME__ = 'DOMPurify dist'; ``` -------------------------------- ### Build Minified UMD Bundle Source: https://github.com/cure53/dompurify/blob/main/README.md Build only a minified UMD bundle. This is suitable for production deployment to reduce file size. ```bash npm run build:umd:min ``` -------------------------------- ### Mutation XSS Example Markup Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This HTML snippet represents a potential mutation XSS payload that might be parsed differently by a browser after initial sanitization. ```html

``` -------------------------------- ### Run happy-dom Tests Source: https://github.com/cure53/dompurify/blob/main/README.md Run the test suite through happy-dom. This environment is unsupported but kept for robustness checks. ```bash npm run test:happydom ``` -------------------------------- ### Build All Rollup Bundles Source: https://github.com/cure53/dompurify/blob/main/README.md Build all distribution bundles using Rollup. This script encompasses the creation of various module formats. ```bash npm run build:rollup ``` -------------------------------- ### Build Project Assets Source: https://github.com/cure53/dompurify/blob/main/README.md Build type declarations and distribution bundles, then fix and clean up generated types. This is the primary build script for creating distributable artifacts. ```bash npm run build ``` -------------------------------- ### Post-process Generated Type Files Source: https://github.com/cure53/dompurify/blob/main/README.md Run a script to post-process generated TypeScript type files. This is a specific step within the overall build process. ```bash npm run build:fix-types ``` -------------------------------- ### Verify Release Artifact Signature with Sigstore Source: https://github.com/cure53/dompurify/blob/main/SECURITY.md Verify a release artifact against its Sigstore bundle. This command checks the integrity and authenticity of downloaded archives. ```bash cosign verify-blob \ --bundle .tar.gz.sigstore.json \ --certificate-identity-regexp 'https://github.com/cure53/DOMPurify/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ .tar.gz ``` -------------------------------- ### Build CommonJS Bundle Source: https://github.com/cure53/dompurify/blob/main/README.md Build only the CommonJS bundle. This is typically used in Node.js environments. ```bash npm run build:cjs ``` -------------------------------- ### Generate Local Coverage Report Source: https://github.com/cure53/dompurify/blob/main/README.md Build an instrumented bundle, run the jsdom test suite, and generate a local HTML line/branch coverage report. This report is scoped to jsdom only and not run in CI. ```bash npm run coverage ``` -------------------------------- ### Build Unminified UMD Bundle Source: https://github.com/cure53/dompurify/blob/main/README.md Build only an unminified UMD (Universal Module Definition) bundle. This is useful for development and debugging. ```bash npm run build:umd ``` -------------------------------- ### Build ES Module Bundle Source: https://github.com/cure53/dompurify/blob/main/README.md Build only the ES module bundle. This is intended for use in modern JavaScript environments that support ES modules. ```bash npm run build:es ``` -------------------------------- ### Format Markdown Files Source: https://github.com/cure53/dompurify/blob/main/README.md Apply Prettier formatting specifically to Markdown files. This ensures consistent documentation style. ```bash npm run format:md ``` -------------------------------- ### Prototype Pollution Leading to Sanitizer Downgrade Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This example demonstrates how prototype pollution in the surrounding JavaScript environment can compromise DOMPurify's default configuration. This was a vulnerability in versions 3.0.1–3.3.3. ```javascript // Pollution happens elsewhere in the application. Object.prototype.tagNameCheck = /.*/; Object.prototype.attributeNameCheck = /.*/; // Later, with default config: const clean = DOMPurify.sanitize(''); ``` -------------------------------- ### Run Fuzzing Tests Source: https://github.com/cure53/dompurify/blob/main/README.md Execute a small fuzzer that covers the sanitize() function and CONFIG options. This helps uncover unexpected behavior with various inputs. ```bash npm run test:fuzz ``` -------------------------------- ### Custom Element Attribute Check with TagName Context Source: https://github.com/cure53/dompurify/blob/main/README.md This example shows how to use the `attributeNameCheck` predicate function to receive both the attribute name and the tag name, enabling context-specific attribute filtering for custom elements. ```javascript // Example with attributeNameCheck receiving tagName as a second parameter const clean = DOMPurify.sanitize( '', { CUSTOM_ELEMENT_HANDLING: { tagNameCheck: (tagName) => tagName.match(/^element-(one|two)$/), attributeNameCheck: (attr, tagName) => { if (tagName === 'element-one') { return ['attribute-one'].includes(attr); } else if (tagName === 'element-two') { return ['attribute-two'].includes(attr); } else { return false; } }, allowCustomizedBuiltInElements: false, }, } ); // ``` -------------------------------- ### Add Multiple Hooks Source: https://github.com/cure53/dompurify/blob/main/demos/hooks-removal-demo.html Shows how to add multiple hooks to the same event ('beforeSanitizeAttributes') and a hook to a different event ('beforeSanitizeElements'). This allows for sequential modifications. ```javascript // Demonstrating adding multiple hooks DOMPurify.addHook('beforeSanitizeAttributes', uppercaseHook); DOMPurify.addHook('beforeSanitizeAttributes', bigHook); DOMPurify.addHook('beforeSanitizeElements', strongHook); clean = DOMPurify.sanitize(dirty); document.getElementById('sanitized').innerHTML += clean; ``` -------------------------------- ### MathML Sanitization with Data URI Source: https://github.com/cure53/dompurify/blob/main/website/index.html Sanitizes a MathML string containing a data URI with a script tag. This example tests DOMPurify's ability to handle MathML and prevent script execution from data URIs. ```javascript const examples = { mathml: 'MathML' }; ``` -------------------------------- ### Run CI Test Flow Source: https://github.com/cure53/dompurify/blob/main/README.md Execute the complete Continuous Integration test flow, including jsdom and Playwright tests. ```bash npm run test:ci ``` -------------------------------- ### Lint Sources Source: https://github.com/cure53/dompurify/blob/main/README.md Lint the project sources using ESLint via xo. This ensures code consistency and adherence to project standards. ```bash npm run lint ``` -------------------------------- ### Configure DOMPurify to Avoid Internal Trusted Types Policy Source: https://github.com/cure53/dompurify/blob/main/README.md This example shows how to prevent DOMPurify from creating its own internal Trusted Types policy by setting TRUSTED_TYPES_POLICY to null. This is useful when you are managing your own policy and want to avoid CSP conflicts. ```javascript window.trustedTypes.createPolicy('my-organization', { createHTML: (input) => DOMPurify.sanitize(input, { TRUSTED_TYPES_POLICY: null }), }); ``` -------------------------------- ### Create a Custom Trusted Types Policy Source: https://github.com/cure53/dompurify/blob/main/demos/trusted-types-demo.html Define a custom Trusted Types policy that performs specific sanitization logic, such as replacing characters or validating URLs. This example shows a policy that replaces '<' with '<' and validates script URLs. ```javascript // You can use policies that don't use DOMPurify as well. const myPolicy = trustedTypes.createPolicy('my-policy', { // This code block needs security review, as it's capable of causing DOM XSS. createHTML(dirty) { return dirty.replace(/
', { CUSTOM_ELEMENT_HANDLING: { tagNameCheck: (tagName) => tagName.match(/^foo-/), // allow all tags starting with "foo-" attributeNameCheck: (attr) => attr.match(/baz/), // allow all containing "baz" allowCustomizedBuiltInElements: true, // allow customized built-ins }, } ); //
``` -------------------------------- ### Sanitize SVG for Image Tag with Namespace Hook Source: https://github.com/cure53/dompurify/blob/main/demos/README.md Use this hook to re-add 'xmlns' and 'xmlns:xlink' attributes to SVG elements after sanitization, which is crucial for SVGs to render correctly when embedded in an `` tag. This is especially useful for SVGs generated by tools like Illustrator. The example also demonstrates allowing the 'filter' tag during sanitization. ```javascript // Add a hook to post-process the sanitized SVG root: re-add the // namespaces (added by tools like Illustrator, stripped during // sanitization) that an -embedded SVG needs to render DOMPurify.addHook('afterSanitizeAttributes', function (node) { if (node.tagName && node.tagName.toLowerCase() === 'svg') { node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); node.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); } }); // Clean the SVG string and allow the "filter" tag const clean = DOMPurify.sanitize(dirty, { ADD_TAGS: ['filter'] }); // Show the sanitized content in an element const img = new Image(); img.src = 'data:image/svg+xml;base64,' + window.btoa(clean); document.getElementById('sanitized').appendChild(img); ``` -------------------------------- ### Sanitize with isomorphic-dompurify Source: https://github.com/cure53/dompurify/blob/main/README.md Use DOMPurify via the isomorphic-dompurify package for cross-environment sanitization. ```javascript import DOMPurify from 'isomorphic-dompurify'; const clean = DOMPurify.sanitize('hello'); ``` -------------------------------- ### Allow Safe MathML and SVG (No SVG Filters) Source: https://github.com/cure53/dompurify/blob/main/README.md Enable the MathML and SVG profiles, allowing their respective safe elements but excluding SVG Filters. This configuration is suitable for mixed MathML and SVG content. ```javascript const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { mathMl: true, svg: true }, }); ``` -------------------------------- ### Run Local Tests Source: https://github.com/cure53/dompurify/blob/main/README.md Execute local tests to ensure the project's integrity. This command lints sources, runs tests through jsdom, and performs browser tests using Playwright. ```bash npm run test ``` -------------------------------- ### Remove All Hooks Source: https://github.com/cure53/dompurify/blob/main/demos/hooks-removal-demo.html Illustrates adding hooks and then removing all of them using `removeAllHooks()`. This is useful for resetting DOMPurify to its default state. ```javascript // Adding hooks and then using removeAllHooks DOMPurify.addHook('beforeSanitizeAttributes', uppercaseHook); DOMPurify.addHook('beforeSanitizeAttributes', bigHook); clean = DOMPurify.sanitize(dirty); document.getElementById('sanitized').innerHTML += clean; DOMPurify.removeAllHooks(); clean = DOMPurify.sanitize(dirty); document.getElementById('sanitized').innerHTML += clean; ``` -------------------------------- ### Format Code and Markdown Source: https://github.com/cure53/dompurify/blob/main/README.md Format JavaScript/TypeScript and Markdown sources using Prettier. This maintains consistent code style across the project. ```bash npm run format ``` -------------------------------- ### Sanitize for Template Systems Source: https://github.com/cure53/dompurify/blob/main/README.md Use this option to strip template-like syntax ({{...}}, ${...}, <%...%>) to make output safe for template systems. This mode is not recommended for production due to potential risks. ```javascript const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_TEMPLATES: true }); ``` -------------------------------- ### Adding Data URI Tags Source: https://github.com/cure53/dompurify/blob/main/README.md This snippet demonstrates how to extend the list of elements that can safely use Data URIs by providing an array of tag names to `ADD_DATA_URI_TAGS`. ```javascript // extend the existing array of elements that can use Data URIs const clean = DOMPurify.sanitize(dirty, { ADD_DATA_URI_TAGS: ['a', 'area'] }); ``` -------------------------------- ### Server-Side DOM Assumptions Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Highlights the critical difference between browser and server-side DOM parsing, warning against assuming security based on browser tests alone. ```text Bad assumption: "It passed in Chrome, so the server-side sanitizer is safe." Better: "Test the exact DOM implementation you deploy." ``` -------------------------------- ### Format JavaScript/TypeScript Sources Source: https://github.com/cure53/dompurify/blob/main/README.md Apply Prettier formatting specifically to JavaScript and TypeScript files. This ensures consistent code style for source files. ```bash npm run format:js ``` -------------------------------- ### Open All Links in New Window with Hook Source: https://github.com/cure53/dompurify/blob/main/demos/README.md The `afterSanitizeAttributes` hook ensures all links open in a new tab or window by setting the `target` attribute to `_blank` or `xlink:show` to `new`. ```javascript // Add a hook to make all links open a new window DOMPurify.addHook('afterSanitizeAttributes', function (node) { // set all elements owning target to target=_blank if ('target' in node) { node.setAttribute('target', '_blank'); } // set non-HTML/MathML links to xlink:show=new if ( !node.hasAttribute('target') && (node.hasAttribute('xlink:href') || node.hasAttribute('href')) ) { node.setAttribute('xlink:show', 'new'); } }); // Clean HTML string and write into our DIV const clean = DOMPurify.sanitize(dirty); ``` -------------------------------- ### Import and Sanitize (ES Modules) Source: https://github.com/cure53/dompurify/blob/main/README.md Import DOMPurify using ES module syntax and sanitize a string. This is common in frameworks like Angular. ```javascript import DOMPurify from 'dompurify'; const clean = DOMPurify.sanitize('hello there'); ``` -------------------------------- ### Basic DOMPurify Sanitation Source: https://github.com/cure53/dompurify/blob/main/demos/README.md Demonstrates the most basic usage of DOMPurify with default settings to sanitize an HTML string. ```javascript // Clean HTML string and write into our DIV const clean = DOMPurify.sanitize(dirty); ``` -------------------------------- ### DOM Sanitization Process Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History Illustrates the typical flow of DOM-based sanitization, from source string to serialization. This process highlights where DOMPurify operates within the browser's parsing and DOM construction. ```text source string -> browser parser -> DOM tree -> sanitizer walk -> serialization ``` -------------------------------- ### Include DOMPurify (Minified) Source: https://github.com/cure53/dompurify/blob/main/README.md Include the minified and tested production version of DOMPurify in your HTML using a script tag. Source maps are available. ```html ``` -------------------------------- ### Comparison of Parser Repair Mechanisms Source: https://github.com/cure53/dompurify/wiki/Attack-Classes-&-Bypass-History This text snippet contrasts different parser repair mechanisms, including depth-limit flattening, nesting-based mXSS, and foster parenting, highlighting their distinct approaches to handling malformed HTML. ```text Depth-limit flattening: too much nesting changes ancestry. Nesting-based mXSS: flattening/repair plus serialization creates a new tree. Foster parenting: table insertion rules relocate misplaced nodes. ``` -------------------------------- ### DOMPurify with Allowed Tags Configuration Source: https://github.com/cure53/dompurify/blob/main/demos/README.md Shows how to configure DOMPurify to only permit specific HTML tags like '

' and '#text', while preserving their text content but not nested elements. ```javascript // Specify a configuration directive, only

elements allowed // Note: We want to also keep

's text content, so we add #text too const config = { ALLOWED_TAGS: ['p', '#text'], KEEP_CONTENT: false }; // Clean HTML string and write into our DIV const clean = DOMPurify.sanitize(dirty, config); ```