"""Rich-text HTML sanitization (XSS defense) using nh3 (ammonia bindings). Applied server-side to every rich-text field before it is stored.""" import nh3 _ALLOWED_TAGS = { "p", "br", "div", "span", "strong", "b", "em", "i", "u", "s", "sub", "sup", "ul", "ol", "li", "h1", "h2", "h3", "h4", "blockquote", "pre", "code", "a", "hr", "table", "thead", "tbody", "tr", "th", "td", } _ALLOWED_ATTRIBUTES = { "a": {"href", "title"}, "th": {"colspan", "rowspan"}, "td": {"colspan", "rowspan"}, } def sanitize_html(value: str | None) -> str | None: if value is None: return None cleaned = nh3.clean( value, tags=_ALLOWED_TAGS, attributes=_ALLOWED_ATTRIBUTES, link_rel="noopener noreferrer", url_schemes={"http", "https", "mailto"}, ) return cleaned