Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network-accessible with no auth, no user interaction, and unchanged scope; impact is availability-only matching scheduler exhaustion with no confidentiality or integrity consequence.
Primary rating from Vendor (EEF).
CVSS VectorVendor: EEF
Lifecycle Timeline
3DescriptionCVE.org
Inefficient Algorithmic Complexity vulnerability in the traversal engine in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU and memory via a flat run of sibling elements in sanitized HTML. The list clause of HtmlSanitizeEx.Traverser.traverse/2 recurses on the tail of a sibling list and then evaluates List.flatten([head] ++ tail) over the already flattened result, so every one of n siblings copies and re-walks the entire remaining tail. The flattening is only needed for the rare case where scrub returns several replacement nodes for one node, but the cost is paid across the whole tail at every step, making traversal quadratic in sibling count.
The traverser sits on every public entry point, so no particular scrubber or configuration is required and the payload needs only allowed tags. A 160 KB body of 20,000 sibling elements occupies a scheduler for roughly 1.7 seconds, and the cost grows faster than the body does.
This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
AnalysisAI
Quadratic CPU and memory exhaustion in html_sanitize_ex affects all applications that accept user-supplied HTML for sanitization, regardless of scrubber configuration. The traversal engine's list clause performs a redundant List.flatten over the entire remaining sibling tail at every recursion step, making sanitization cost O(n²) in sibling count rather than O(n). A 160 KB input of 20,000 sibling elements monopolizes a BEAM scheduler for approximately 1.7 seconds per request; no public exploit has been identified at time of analysis, and the flaw is not listed in CISA KEV, but the attack requires no authentication and no special server configuration.
Technical ContextAI
html_sanitize_ex is an Elixir HTML sanitization library (CPE: cpe:2.3:a:rrrene:html_sanitize_ex) running on the BEAM runtime. The root cause is CWE-407 (Algorithmic Complexity): in the list clause of HtmlSanitizeEx.Traverser.traverse/2, the original implementation recursively processed the tail and then called List.flatten([head] ++ tail) at each recursion depth. Because the recursive call already returns a flattened structure, this flatten redundantly re-traverses and copies all n-1 remaining siblings when processing sibling 1, all n-2 when processing sibling 2, and so on - yielding O(n²) total work. The fix (commit 9f5ccedbed230930813f992a1e6906fcf485981e) replaces the recursive head/tail decomposition with Enum.reduce/3 building an accumulator list in reverse, then a single terminal List.flatten after all siblings are processed, restoring O(n) traversal. The traverser sits beneath every public sanitization entry point, meaning the flaw is architecture-wide rather than isolated to a specific scrubber.
RemediationAI
Upgrade html_sanitize_ex to version 1.5.3 or later by updating mix.exs to specify ~> 1.5.3 or >= 1.5.3 and running mix deps.get followed by mix deps.compile; the specific fix is in commit 9f5ccedbed230930813f992a1e6906fcf485981e. The vendor security advisory at https://github.com/rrrene/html_sanitize_ex/security/advisories/GHSA-463q-p2fr-mh9p should be consulted for any additional guidance. If an immediate upgrade is not feasible, enforce a hard request body-size limit (e.g., 20-40 KB) in the HTTP layer before content reaches the sanitizer - this limits the maximum sibling count per request but does not eliminate risk because even sub-limit payloads impose elevated scheduler cost relative to normal HTML; this is a partial compensating control only. Additionally, rate-limit sanitization endpoints per IP and consider placing the sanitization call in a separate supervised process with a timeout to prevent a single blocked scheduler from starving the application.
More in Html Sanitize Ex
View allCPU exhaustion via quadratic regex backtracking in rrrene/html_sanitize_ex, an Elixir HTML sanitization library, allows
html_sanitize_ex's HTML5 scrubber (versions 0.3.1 through 1.5.2) permits the `form` and `formaction` attributes to survi
Open redirect in html_sanitize_ex (Elixir, versions 0.3.1 through 1.5.2) allows remote attackers to force page visitors
html_sanitize_ex's HTML5 scrubber (versions 0.3.1 through before 1.5.3) passes attacker-controlled URIs through the `dat
CSS at-rule injection in html_sanitize_ex (Elixir, versions 0.3.1-1.5.3) allows unauthenticated remote users to embed `@
Same weakness CWE-407 – Inefficient Algorithmic Complexity
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-54085
GHSA-684p-mhw3-3cwq