npm / sanitize-html
sanitize-html
What changed in sanitize-html 2, from its official release notes, upgrade guides and advisories. Also covers @types/sanitize-html. Sources checked 2026-10-18.
7 breaking13 security1 new APIs and options4 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initsanitize-html 225 changes
Breaking changes 7
Removed the dependency because sanitize-html used only a small part of its functionality, so security scanner reports for deepmerge no longer appear for sanitize-html users.
Fallback markup remains sanitized but is limited to eight nested iframe elements; deeper fallback is escaped as text, and the current nesting depth carries into nested calls so nestingLimit applies to the whole output.
Diagnostic messages are now single lines without decorative line breaks or a warning icon; their wording is unchanged.
For allowed meta elements, refresh destinations in content are checked against allowedSchemes or allowedSchemesByTag.meta; rejected or unparseable refresh content is removed.
Configurations allowing svg or math together with textarea or xmp no longer re-emit raw-text contents unescaped, preventing non-allowlisted markup from surviving sanitization.
sanitize-html now requires Node.js >=22.12.0 because htmlparser2 is ESM-only from version 11 onward.
More attributes are protected against unsafe URL types where those URLs are not appropriate.
Security 13
Markup preserved inside a disallowed iframe is no longer escaped and is fully sanitized according to the same rules as the original input.
Animation elements and attributeName are matched by local name, ignoring prefixes, so namespace-prefixed elements such as svg:animate are recognized when dropping URL-retargeting animations.
ApostropheCMS: Stored XSS via SVG SMIL URI-list scheme-policy bypass
Fixed an XSS / URL scheme policy bypass when configurations allow SVG animation elements together with attributeName and an animation value attribute.
ApostropheCMS: Mutation-XSS / allowedTags bypass via literal
</textarea/>solidus closeConfigurations allowing textarea or xmp are protected against trailing-solidus end tags causing following non-allowlisted markup to be re-emitted as raw text.
Nonstandard
nonTextTagsconfigurations no longer let nested tags pass through without sanitization unless they are expressly allowed.sanitize-html has incomplete URI scheme validation in that allows javascript: URIs through action, formaction, data, poster, and background attributes
Apostrophe has default XSS via
xmpraw-text passthrough insanitize-htmlThe xmp tag could pass forbidden markup through sanitize-html even when xmp was not explicitly allowed; users should update immediately.
Fixes an XSS vulnerability that affected configurations explicitly permitting option tags.
sanitize-html allowedTags Bypass via Entity-Decoded Text in nonTextTags Elements
These references are now correctly decoded, preventing them from bypassing javascript: URL detection.
New APIs and options 1
A console-shaped logger option routes sanitize-html diagnostics to an application logging pipeline; missing methods and an omitted option fall back to the console.
Fixes and other changes 4
Per-tag scheme allowlists now apply to srcset and imagesrcset URLs instead of falling back to the global allowedSchemes.
transformTags can emit text when textFilter is set, even if the tag is initially empty.
Entities inside raw text elements such as textarea and option are no longer double-encoded.
Unclosed tags such as
<hellono longer return an empty string inescapeandrecursiveEscapemodes.