DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. It's written in JavaScript and works in all modern browsers (Safari, Opera (15+), Internet Explorer (10+), Firefox and Chrome - as well as almost anything else using Blink or WebKit). DOMPurify provides comprehensive protection against XSS attacks by stripping dangerous elements and features while preserving safe content.
npm install dompurifyimport DOMPurify from "dompurify";For CommonJS:
const DOMPurify = require("dompurify");Browser (UMD):
<script src="./node_modules/dompurify/dist/purify.min.js"></script>
<!-- DOMPurify is available as global variable -->import DOMPurify from "dompurify";
// Basic sanitization - returns clean HTML string
const clean = DOMPurify.sanitize('<script>alert("xss")</script><b>hello</b>');
// Result: "<b>hello</b>"
// Sanitize with custom configuration
const cleanCustom = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong'],
ALLOWED_ATTR: ['href']
});
// Return DOM nodes instead of string
const cleanNode = DOMPurify.sanitize(dirty, { RETURN_DOM: true });
// Check if attribute is valid
const isValid = DOMPurify.isValidAttribute('a', 'href', 'https://example.com');DOMPurify is designed around several key architectural concepts:
Primary sanitization functionality that removes dangerous content while preserving safe HTML, MathML, and SVG elements.
/**
* Main sanitization function with multiple output format options
*/
function sanitize(dirty: string | Node, cfg?: Config): string;
function sanitize(dirty: string | Node, cfg: Config & { RETURN_DOM: true }): Node;
function sanitize(dirty: string | Node, cfg: Config & { RETURN_DOM_FRAGMENT: true }): DocumentFragment;
function sanitize(dirty: string | Node, cfg: Config & { RETURN_TRUSTED_TYPE: true }): TrustedHTML;
function sanitize(dirty: Node, cfg: Config & { IN_PLACE: true }): Node;System for controlling sanitization behavior through extensive configuration options.
/**
* Set global configuration for all subsequent sanitize calls
*/
function setConfig(cfg?: Config): void;
/**
* Clear the current configuration, reverting to defaults
*/
function clearConfig(): void;
interface Config {
ADD_ATTR?: string[];
ADD_DATA_URI_TAGS?: string[];
ADD_TAGS?: string[];
ADD_URI_SAFE_ATTR?: string[];
ALLOW_ARIA_ATTR?: boolean;
ALLOW_DATA_ATTR?: boolean;
ALLOW_UNKNOWN_PROTOCOLS?: boolean;
ALLOW_SELF_CLOSE_IN_ATTR?: boolean;
ALLOWED_ATTR?: string[];
ALLOWED_TAGS?: string[];
ALLOWED_NAMESPACES?: string[];
ALLOWED_URI_REGEXP?: RegExp;
CUSTOM_ELEMENT_HANDLING?: {
tagNameCheck?: RegExp | ((tagName: string) => boolean) | null;
attributeNameCheck?: RegExp | ((attributeName: string) => boolean) | null;
allowCustomizedBuiltInElements?: boolean;
};
FORBID_ATTR?: string[];
FORBID_CONTENTS?: string[];
FORBID_TAGS?: string[];
FORCE_BODY?: boolean;
HTML_INTEGRATION_POINTS?: Record<string, boolean>;
IN_PLACE?: boolean;
KEEP_CONTENT?: boolean;
MATHML_TEXT_INTEGRATION_POINTS?: Record<string, boolean>;
NAMESPACE?: string;
PARSER_MEDIA_TYPE?: DOMParserSupportedType;
RETURN_DOM_FRAGMENT?: boolean;
RETURN_DOM?: boolean;
RETURN_TRUSTED_TYPE?: boolean;
SAFE_FOR_TEMPLATES?: boolean;
SAFE_FOR_XML?: boolean;
SANITIZE_DOM?: boolean;
SANITIZE_NAMED_PROPS?: boolean;
SANITIZE_NAMED_PROPS_PREFIX?: string;
SVG_TEXT_INTEGRATION_POINTS?: Record<string, boolean>;
TRUSTED_TYPES_POLICY?: TrustedTypePolicy | false;
USE_PROFILES?: UseProfilesConfig | false;
WHOLE_DOCUMENT?: boolean;
}Event-driven system for custom sanitization logic and extending DOMPurify functionality.
/**
* Add a hook function to execute at specific sanitization points
*/
function addHook(entryPoint: HookName, hookFunction: HookFunction): void;
/**
* Remove a specific hook function or the last added hook
*/
function removeHook(entryPoint: HookName, hookFunction?: HookFunction): HookFunction | undefined;
/**
* Remove all hooks at a specific entry point
*/
function removeHooks(entryPoint: HookName): void;
/**
* Remove all hooks from all entry points
*/
function removeAllHooks(): void;
type HookName =
| 'beforeSanitizeElements'
| 'afterSanitizeElements'
| 'beforeSanitizeAttributes'
| 'afterSanitizeAttributes'
| 'uponSanitizeElement'
| 'uponSanitizeAttribute'
| 'beforeSanitizeShadowDOM'
| 'afterSanitizeShadowDOM'
| 'uponSanitizeShadowNode';Utility functions for validating attribute values and checking browser support.
/**
* Check if an attribute value is valid for a given tag and attribute name
*/
function isValidAttribute(tag: string, attr: string, value: string): boolean;
/**
* Indicates whether the current environment supports DOMPurify
*/
readonly isSupported: boolean;
/**
* Version string of the DOMPurify library
*/
readonly version: string;
/**
* Array of elements that DOMPurify removed during the last sanitization
*/
readonly removed: Array<RemovedElement | RemovedAttribute>;interface DOMPurify {
(root?: WindowLike): DOMPurify;
version: string;
removed: Array<RemovedElement | RemovedAttribute>;
isSupported: boolean;
sanitize: SanitizeFunction;
setConfig(cfg?: Config): void;
clearConfig(): void;
isValidAttribute(tag: string, attr: string, value: string): boolean;
addHook(entryPoint: HookName, hookFunction: HookFunction): void;
removeHook(entryPoint: HookName, hookFunction?: HookFunction): HookFunction | undefined;
removeHooks(entryPoint: HookName): void;
removeAllHooks(): void;
}
interface RemovedElement {
element: Node;
}
interface RemovedAttribute {
attribute: Attr | null;
from: Node;
}
type WindowLike = Pick<typeof globalThis,
| 'DocumentFragment'
| 'HTMLTemplateElement'
| 'Node'
| 'Element'
| 'NodeFilter'
| 'NamedNodeMap'
| 'HTMLFormElement'
| 'DOMParser'
> & {
document?: Document;
MozNamedAttrMap?: typeof window.NamedNodeMap;
} & Pick<TrustedTypesWindow, 'trustedTypes'>;
type TrustedHTML = any; // Browser TrustedHTML type when supported
type TrustedTypePolicy = any; // Browser TrustedTypePolicy type
type TrustedTypesWindow = any; // Browser TrustedTypes window extension
type UseProfilesConfig = { html?: boolean; svg?: boolean; svgFilters?: boolean; mathMl?: boolean };
type DOMParserSupportedType = 'application/xhtml+xml' | 'text/html' | 'text/xml' | 'image/svg+xml';
type HookFunction = NodeHook | ElementHook | DocumentFragmentHook | UponSanitizeElementHook | UponSanitizeAttributeHook;
type NodeHook = (this: DOMPurify, currentNode: Node, hookEvent: null, config: Config) => void;
type ElementHook = (this: DOMPurify, currentNode: Element, hookEvent: null, config: Config) => void;
type DocumentFragmentHook = (this: DOMPurify, currentNode: DocumentFragment, hookEvent: null, config: Config) => void;
type UponSanitizeElementHook = (this: DOMPurify, currentNode: Node, hookEvent: UponSanitizeElementHookEvent, config: Config) => void;
type UponSanitizeAttributeHook = (this: DOMPurify, currentNode: Element, hookEvent: UponSanitizeAttributeHookEvent, config: Config) => void;
interface UponSanitizeElementHookEvent {
tagName: string;
allowedTags: Record<string, boolean>;
}
interface UponSanitizeAttributeHookEvent {
attrName: string;
attrValue: string;
keepAttr: boolean;
allowedAttributes: Record<string, boolean>;
forceKeepAttr?: boolean;
}