For AI agents: llms.txt is a short guide that sends you to the rules your problem needs, and rules.json holds every rule of this playbook as JSON.
Recommended Open source
Use DOMPurify or nh3 to clean user HTML
Clean any HTML that users write with DOMPurify in JavaScript or nh3 in Python, with a short allow list of tags and attributes.
Cost
Open source. DOMPurify is Apache-2.0 or MPL-2.0, and nh3 is MIT. Both are free to use in any project.
How to do it
DOMPurify first came out in May 2014, and 3.4.17 shipped on 12 October 2026. npm counted about 42 million downloads in the week to 18 October 2026. OWASP's cross-site scripting cheat sheet names it as the sanitiser OWASP recommends. On a Node.js server, give it a window from jsdom. In Python, nh3 wraps ammonia, a sanitiser written in Rust. It is still on version 0.3, first published in August 2021, so record it as an exception. Version 0.3.7 shipped on 23 August 2026, with about 9 million weekly downloads. Bleach was the usual Python choice, but its README says it has been unmaintained since 5 June 2026. Escape everything else as Escape everything you show says. Choose something else when the text needs no markup. Plain text with escaping needs no sanitiser at all.
Examples
Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.
JavaScript example
import DOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
const purify = DOMPurify(new JSDOM('').window);
const ALLOWED_TAGS = ['p', 'br', 'strong', 'em', 'ul', 'ol', 'li', 'a'];
export const cleanReview = (html) => purify.sanitize(html, { ALLOWED_TAGS, ALLOWED_ATTR: ['href'] });
Python example
import nh3
ALLOWED_TAGS = {"p", "br", "strong", "em", "ul", "ol", "li", "a"}
def clean_review(html: str) -> str:
return nh3.clean(html, tags=ALLOWED_TAGS, attributes={"a": {"href"}}, url_schemes={"http", "https"})
How to check
A test cleans <img src=x onerror=alert(1)> and <a href="javascript:alert(1)">x</a>. Neither the onerror attribute nor the javascript: link is in the output. The project has no dependency on bleach.
Sources
Related rules
- Escape everything you show in Security testing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/stack/web-frameworks/html-sanitiser">Agent Wranglers software choices playbook</a>. In code you write, add a comment next to it with the same link.