PhoenixKit.Utils.HtmlSanitizer (phoenix_kit v2.2.0)

Copy Markdown View Source

HTML sanitization for user-supplied rich text.

Backed by MDEx.safe_html/2 — an ammonia-based parsed allowlist. It builds a real DOM, keeps only known-good tags and attributes, validates URL schemes per attribute, and re-serializes. It does not pattern-match on markup, which is why it holds up where the previous regex implementation did not (see sanitize_html/1).

What survives

Ordinary rich text: block elements (p, div, hr, h1-h6, blockquote, pre, code), inline elements (span, strong, em, u, s, a, sub, sup), lists, tables, and img. Relative, absolute, anchor, mailto: and tel: URLs are preserved, as are class on any tag and target on links.

What is removed

Script and style elements, event-handler attributes, dangerous URL schemes (javascript:, data:, …) including entity-encoded spellings such as javascript:, and embedding elements (iframe, object, embed, svg, math).

Attributes outside the allowlist go too, and the allowlist is narrower than the one this module shipped before the rewrite. Most notably id is dropped from every tag, so href="#..." can only reach an anchor the application itself rendered, not one stored in the content. Also gone: rel (re-stamped as noopener noreferrer on every link), <input> — so Markdown task-list checkboxes vanish — and <tfoot>. sanitize_html/1 carries the reasoning and the knobs.

Output is normalised

Because the result is re-serialized from a parse tree, it is valid HTML rather than a lightly-edited copy of the input: attribute values come back quoted, void elements lose a self-closing slash (<br/><br>), <table> gains an implicit <tbody>, and links gain rel="noopener noreferrer". Compare rendered meaning, not exact strings, when asserting on sanitized output.

Usage

PhoenixKit.Utils.HtmlSanitizer.sanitize("<p>Hello</p><script>alert('xss')</script>")
#=> "<p>Hello</p>"

PhoenixKit.Utils.HtmlSanitizer.sanitize(~s|<a href="javascript:alert(1)">Click</a>|)
#=> "<a rel=\"noopener noreferrer\">Click</a>"

Summary

Functions

Sanitizes HTML content by removing dangerous elements and attributes.

Sanitizes all rich_text fields in an entity data map.

Functions

sanitize(html)

Sanitizes HTML content by removing dangerous elements and attributes.

Returns sanitized HTML string that is safe to render.

Parameters

  • html - The HTML string to sanitize

Examples

iex> PhoenixKit.Utils.HtmlSanitizer.sanitize("<p onclick="alert('xss')">Hello</p>")
"<p>Hello</p>"

sanitize_rich_text_fields(fields_definition, data)

Sanitizes all rich_text fields in an entity data map.

Takes entity field definitions and data, returns data with all rich_text fields sanitized.

Parameters

  • fields_definition - List of field definition maps
  • data - Map of field key => value

Examples

iex> fields = [%{"type" => "rich_text", "key" => "content"}]
iex> data = %{"content" => "<script>alert('xss')</script><p>Hello</p>"}
iex> PhoenixKit.Utils.HtmlSanitizer.sanitize_rich_text_fields(fields, data)
%{"content" => "<p>Hello</p>"}