Tiptapex.Renderer.URL (Tiptapex v0.1.2)

Copy Markdown View Source

URL and CSS value sanitization for Tiptapex.Renderer.

These allow-lists are the core XSS defense: link/image/video URLs must be http(s), mailto, or relative; iframes are only ever emitted for canonical YouTube embed URLs rebuilt from a validated video id; CSS values must match a strict grammar that cannot break out of a style attribute.

Summary

Functions

Coerces a width attribute to integer pixels.

Validates a CSS value for inline style emission (colors, font sizes, font families, line heights). The grammar admits no ;, braces, quotes, url(, or escapes, so a value can never break out of its declaration.

Validates a URL for an img src.

Validates a user-supplied URL for href/src attributes.

Validates a text-align value.

Normalizes any of the common YouTube URL shapes to the canonical embed URL, validating the video id. This is the ONLY URL ever placed in an iframe src; anything that doesn't resolve here drops the whole node.

Functions

int_width(value)

@spec int_width(term()) :: {:ok, pos_integer()} | :error

Coerces a width attribute to integer pixels.

safe_css_value(value)

@spec safe_css_value(term()) :: {:ok, binary()} | :error

Validates a CSS value for inline style emission (colors, font sizes, font families, line heights). The grammar admits no ;, braces, quotes, url(, or escapes, so a value can never break out of its declaration.

safe_image_url(url)

@spec safe_image_url(term()) :: {:ok, binary()} | :error

Validates a URL for an img src.

Everything safe_url/1 accepts, plus data: URIs for images — which safe_url/1 rejects (a data: link is a navigation vector, but a data: image is inert, and it is the only src Chrome can resolve inside a PDF running header). SVG is included: an SVG loaded through <img> cannot run scripts, which is the only way these are ever rendered.

safe_url(url)

@spec safe_url(term()) :: {:ok, binary()} | :error

Validates a user-supplied URL for href/src attributes.

Accepts absolute http/https/mailto URLs, protocol-relative URLs, and relative paths/fragments. Rejects everything else — notably javascript:, vbscript:, and data: — plus anything containing control characters.

text_align(value)

@spec text_align(term()) :: {:ok, binary()} | :error

Validates a text-align value.

youtube_embed(url)

@spec youtube_embed(term()) :: {:ok, binary()} | :error

Normalizes any of the common YouTube URL shapes to the canonical embed URL, validating the video id. This is the ONLY URL ever placed in an iframe src; anything that doesn't resolve here drops the whole node.

Mirrors toYoutubeEmbed/1 in assets/js/tiptapex/extensions/video.js, but rebuilds the URL from the extracted id instead of passing the original through.