### Create a Basic Custom Scrubber with HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/main.md Use the `__using__` macro to define a custom scrubber module. You can then define allowed tags and their attributes. This example shows how to allow `

` tags with a `class` attribute and `` tags with `href` attributes that start with 'https' or 'mailto'. ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx allow_tag_with_these_attributes("p", ["class"]) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) end MyProject.MyScrubber.sanitize("

Hello

") # => "

Hello

" ``` -------------------------------- ### scrub_attribute/2 Callback Examples Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Examples demonstrating how to use the scrub_attribute/2 callback to either keep an attribute unchanged, modify its value, or remove it entirely. ```elixir # Allow attribute unchanged def scrub_attribute("p", {"class", value}), do: {"class", value} # Modify value def scrub_attribute("a", {"href", value}) do {"href", String.downcase(value)} end # Block attribute def scrub_attribute("img", {"onerror", _}), do: nil ``` -------------------------------- ### Create Custom Scrubber Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/README.md Illustrates how to create a custom scrubber by extending HtmlSanitizeEx and defining allowed tags and attributes. ```APIDOC ## Create Custom Scrubber ### Description Example of defining and using a custom HTML scrubber. ### Functions - `use HtmlSanitizeEx, extend: :basic_html`: Extends an existing scrubber configuration. - `allow_tag_with_these_attributes(tag, attributes)`: Whitelists a tag and its attributes. - `allow_tag_with_uri_attributes(tag, uri_attributes, allowed_schemes)`: Whitelists a tag with URI attributes and specifies allowed schemes. - `YourCustomScrubber.sanitize(html)`: Sanitizes HTML using the custom scrubber configuration. ### Request Example ```elixir defmodule MyApp.MyScrubber do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("div", ["class"]) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) end MyApp.MyScrubber.sanitize(html) ``` ``` -------------------------------- ### Basic HTML Sanitization Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber.md Demonstrates a basic usage of the scrub/2 function with a simple HTML string and the BasicHTML scrubber. ```elixir HtmlSanitizeEx.Scrubber.scrub("

hello

", HtmlSanitizeEx.Scrubber.BasicHTML) # => "

hello

" ``` -------------------------------- ### Full Sanitization Pipeline Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md An end-to-end example showing the traverser integrated within the HTML sanitization pipeline, from parsing to final HTML output. ```elixir html = "

Title

Content

" tree = HtmlSanitizeEx.Parser.parse(html) # tree = [{"h1", [], ["Title"]}, {"p", [], ["Content ", {:script, [], []}}]} scrubbed = HtmlSanitizeEx.Traverser.traverse(tree, HtmlSanitizeEx.Scrubber.BasicHTML) # scrubbed = [{"h1", [], ["Title"]}, {"p", [], ["Content "]}] # (script tag removed) result = HtmlSanitizeEx.Parser.to_html(scrubbed) # result = "

Title

Content

" ``` -------------------------------- ### Doctype Token Examples Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Examples of doctype tokens. ```elixir {:doctype, ["html"]} ``` ```elixir {:doctype, ["html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""]} ``` -------------------------------- ### Comment Token Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Example of a comment token and how it might be scrubbed. ```elixir {:comment, ["This is a comment"]} # Stripped by default (via strip_comments/0 macro): def scrub({:comment, _}), do: "" ``` -------------------------------- ### Elixir Scrubber Callback Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Demonstrates how to define a scrubber callback using the `node_with_children` type for pattern matching. This example shows a basic scrub function for 'p' tags. ```elixir @callback scrub(node_with_children()) :: node_with_children() # Pattern matching in scrubber: def scrub({"p", attributes, children}) do {"p", scrub_attributes("p", attributes), children} end ``` -------------------------------- ### Depth-First Traversal Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md Demonstrates the depth-first traversal order where children are processed before parents. This example shows a simple tree structure and the expected traversal sequence. ```elixir tree = { "div", [], [ {"p", [], ["text1"]}, {"p", [], ["text2"]} ] } # Traversal order: # 1. Traverse first

and its children # 2. Traverse second

and its children # 3. Call scrub on

with processed children ``` -------------------------------- ### Keyword List (Attributes) Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md An example of a keyword list representing HTML element attributes. ```elixir [{"id", "main"}, {"class", "container"}, {"data-test", "x"}] ``` -------------------------------- ### Attribute Tuple Examples Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Examples of attribute tuples, including a boolean attribute. ```elixir {"class", "intro"} ``` ```elixir {"href", "https://example.com"} ``` ```elixir {"data-value", "123"} ``` ```elixir {"disabled", ""} # Boolean attribute ``` ```elixir {"aria-label", "Menu"} ``` -------------------------------- ### Sanitize HTML Examples Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/README.md Demonstrates basic usage of HtmlSanitizeEx for stripping tags, allowing basic HTML, and sanitizing HTML5 with XSS protection. ```APIDOC ## Sanitize HTML ### Description Examples showing how to use the core sanitization functions. ### Functions - `HtmlSanitizeEx.strip_tags(html)`: Strips all HTML tags from the input string. - `HtmlSanitizeEx.basic_html(html)`: Sanitizes HTML, allowing basic formatting tags. - `HtmlSanitizeEx.html5(html)`: Sanitizes HTML5 content with XSS protection, including URI validation. ### Request Example ```elixir # Strip all tags HtmlSanitizeEx.strip_tags("

Hello

") # => "Hello evil" # Allow basic formatting HtmlSanitizeEx.basic_html("

Title

Content

") # => "

Title

Content

" # Allow HTML5 with XSS protection HtmlSanitizeEx.html5("

Content

") # => "

Content

" ``` -------------------------------- ### Complete HtmlSanitizeEx Configuration Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md This example demonstrates a full configuration for HtmlSanitizeEx, allowing a wide range of HTML tags and attributes, including text formatting, structure, lists, links, images, tables, and semantic tags. It also specifies allowed URI schemes for links and images. ```elixir defmodule MyProject.DocumentScrubber do use HtmlSanitizeEx # Remove CDATA and comments (automatic) # remove_cdata_sections_before_scrub() # strip_comments() # === Text Formatting === allow_tag_with_these_attributes("b", []) allow_tag_with_these_attributes("strong", []) allow_tag_with_these_attributes("em", []) allow_tag_with_these_attributes("i", []) allow_tag_with_these_attributes("u", []) allow_tag_with_these_attributes("code", ["class"]) # === Structure === allow_tag_with_these_attributes("p", ["class", "id"]) allow_tag_with_these_attributes("h1", []) allow_tag_with_these_attributes("h2", []) allow_tag_with_these_attributes("h3", []) allow_tag_with_these_attributes("blockquote", ["cite"]) # === Lists === allow_tag_with_these_attributes("ul", []) allow_tag_with_these_attributes("ol", ["start"]) allow_tag_with_these_attributes("li", ["value"]) # === Links (URI validation) === allow_tag_with_uri_attributes("a", ["href"], ["http", "https", "mailto"]) allow_tag_with_these_attributes("a", ["title", "target"]) # === Images (URI validation) === allow_tag_with_uri_attributes("img", ["src"], ["http", "https"]) allow_tag_with_these_attributes("img", ["alt", "width", "height"]) # === Tables === allow_tag_with_these_attributes("table", []) allow_tag_with_these_attributes("thead", []) allow_tag_with_these_attributes("tbody", []) allow_tag_with_these_attributes("tr", []) allow_tag_with_these_attributes("th", ["scope"]) allow_tag_with_these_attributes("td", ["colspan", "rowspan"]) # === Semantic Tags (HTML5) === allow_tag_with_these_attributes("article", ["id"]) allow_tag_with_these_attributes("section", []) allow_tag_with_these_attributes("header", []) allow_tag_with_these_attributes("footer", []) # === Others === allow_tag_with_these_attributes("br", []) allow_tag_with_these_attributes("hr", []) allow_tag_with_these_attributes("span", ["class"]) end ``` -------------------------------- ### Testing CSS Scrubbing Directly Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Provides examples of using `HtmlSanitizeEx.Scrubber.CSS.scrub/1` to test the CSS scrubbing logic with various safe and unsafe CSS inputs. ```APIDOC ## HtmlSanitizeEx.Scrubber.CSS.scrub/1 ### Description Scrub CSS rules, removing malicious properties or values. This function can be used to test the CSS scrubbing logic directly. ### Usage ```elixir # Safe CSS HtmlSanitizeEx.Scrubber.CSS.scrub("color: red; font-size: 14px; margin: 10px; border: 1px solid black") # => "color: red; font-size: 14px; margin: 10px; border: 1px solid black" # Blocked: malicious schemes HtmlSanitizeEx.Scrubber.CSS.scrub("background: url(javascript:alert()); color: blue") # => "color: blue" # Blocked: unknown properties HtmlSanitizeEx.Scrubber.CSS.scrub("color: red; -webkit-filter: blur(20px); opacity: 0.5") # => "color: red; opacity: 0.5" # Blocked: escape sequences HtmlSanitizeEx.Scrubber.CSS.scrub("color: red\A; color: blue") # => "" # Mixed safe/unsafe values (invalid values are removed) HtmlSanitizeEx.Scrubber.CSS.scrub("width: 100px 200px; width: 100px") # => "width: 100px" ``` ``` -------------------------------- ### Full HTML Sanitization Pipeline Example Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/parser.md Demonstrates the complete HTML sanitization process using the HtmlSanitizeEx library. It shows parsing HTML, traversing the tree with a scrubber, and converting the traversed tree back to HTML. ```elixir html = "

Title

Text

" # Pipeline steps: tree = HtmlSanitizeEx.Parser.parse(html) # tree = [{"h1", [], ["Title"]}, {"p", [], ["Text ", {:script, [], []}}]} traversed = HtmlSanitizeEx.Traverser.traverse(tree, HtmlSanitizeEx.Scrubber.BasicHTML) # traversed = [{"h1", [], ["Title"]}, {"p", [], ["Text "]}] # (script tag removed, content kept) result = HtmlSanitizeEx.Parser.to_html(traversed) # result = "

Title

Text

" ``` -------------------------------- ### Extend an Existing Scrubber with HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/main.md Create a new scrubber that inherits rules from an existing one using the `extend:` option in the `use HtmlSanitizeEx` macro. This example extends the `:basic_html` scrubber to also allow `` tags. ```elixir defmodule MyProject.ExtendedBasic do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("small", []) end MyProject.ExtendedBasic.sanitize("Fine print") # => "Fine print" ``` -------------------------------- ### Scrubbing Safe CSS Properties and Values Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Shows an example of valid CSS properties and values that are preserved by the CSS scrubber. ```elixir # Safe: all valid properties and values HtmlSanitizeEx.Scrubber.CSS.scrub( "color: red; font-size: 14px; margin: 10px; border: 1px solid black" ) # => "color: red; font-size: 14px; margin: 10px; border: 1px solid black" ``` -------------------------------- ### Example of NoScrub with script tag Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/built-in-scrubbers.md Demonstrates that the NoScrub scrubber passes script tags through unchanged, offering no XSS protection. ```elixir HtmlSanitizeEx.noscrub("") # => "" ``` -------------------------------- ### Principle of Least Privilege Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Start with a restrictive scrubber configuration, such as `StripTags`, and add only the necessary tags and attributes. This approach minimizes potential security vulnerabilities. ```elixir # Start with StripTags, add only what's needed defmodule MyApp.Scrubbers.Minimal do use HtmlSanitizeEx allow_tag_with_these_attributes("b", []) allow_tag_with_these_attributes("em", []) allow_tag_with_uri_attributes("a", ["href"], ["https"]) end ``` -------------------------------- ### Allowing URI Schemes with allow_tag_with_uri_attributes/3 Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Examples showing how to use allow_tag_with_uri_attributes/3 to whitelist specific URI schemes for attributes within HTML tags. ```elixir allow_tag_with_uri_attributes("a", ["href"], ["http", "https", "mailto"]) allow_tag_with_uri_attributes("img", ["src"], ["http", "https"]) ``` -------------------------------- ### Integrating URI Scrubber with Tag Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/uri-scrubber.md The URI scrubber is called automatically by `allow_tag_with_uri_attributes/3`. This example shows how to configure it for 'a' tags and 'href' attributes. ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx # This expands to use URI scrubbing for href attributes allow_tag_with_uri_attributes("a", ["href"], ["http", "https", "mailto"]) end # When sanitizing: MyProject.MyScrubber.sanitize("
click") # => "click" # (href removed because javascript: not in whitelist) ``` -------------------------------- ### Elixir `html_tree` Examples Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md Illustrates various forms of the `html_tree` type, including single elements with attributes, nested elements, multiple top-level elements, and mixed content with text and inline elements. ```elixir # Single paragraph with attributes {"p", [{"class", "intro"}, {"id", "para1"}], ["Hello world"]} ``` ```elixir # Nested elements {"div", [], [{"p", [], ["text"]}, {"p", [], ["more"]}]} ``` ```elixir # Multiple top-level elements [{"h1", [], ["Title"]}, {"p", [], ["Content"]}] ``` ```elixir # Mixed text and elements {"p", [], ["Start ", {"b", [], ["bold"]}, " end"]} ``` -------------------------------- ### Test Custom Scrubbers Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Thoroughly test your custom scrubbers to ensure they behave as expected and do not introduce security risks. This example demonstrates tests for blocking scripts and preserving basic formatting. ```elixir defmodule MyApp.Scrubbers.UserContentTest do use ExUnit.Case test "blocks scripts" do result = MyApp.Scrubbers.UserContent.sanitize("") assert result == "" end test "preserves basic formatting" do result = MyApp.Scrubbers.UserContent.sanitize("

bold

") assert result == "

bold

" end end ``` -------------------------------- ### Example of NoScrub with image tag and javascript URI Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/built-in-scrubbers.md Shows that the NoScrub scrubber preserves image tags with javascript URIs, highlighting its lack of security. ```elixir HtmlSanitizeEx.noscrub("") # => "" ``` -------------------------------- ### Allowed CSS Measurement Units Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Shows the various measurement units and their examples that are permitted in CSS values. Supports both positive and negative values. ```css 10px ``` ```css 1cm ``` ```css 1.5em ``` ```css 10mm ``` ```css 2ex ``` ```css 1in ``` ```css 12pt ``` ```css 1pc ``` ```css 50% ``` ```css -5px, -1.5em ``` -------------------------------- ### Use Custom HTML Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md After defining a custom scrubber, use its `sanitize/1` function to process HTML content according to the defined rules. This example demonstrates sanitizing HTML with the custom scrubber. ```elixir text = "

Hello

" MyProject.MyScrubber.sanitize(text) # => "

Hello World!

" ``` -------------------------------- ### Define Environment-Specific Scrubbers Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Configure different scrubbers based on your application's environment. This example shows how to set a default scrubber in config.exs and use it within a sanitizer module. ```elixir # config/config.exs config :my_app, :scrubber, :basic_html # lib/my_app/sanitizer.ex defmodule MyApp.Sanitizer do @scrubber Application.compile_env(:my_app, :scrubber, :basic_html) def sanitize(html) do case @scrubber do :basic_html -> HtmlSanitizeEx.basic_html(html) :html5 -> HtmlSanitizeEx.html5(html) :strip_tags -> HtmlSanitizeEx.strip_tags(html) custom_module -> custom_module.sanitize(html) end end end ``` -------------------------------- ### Organize Scrubbers by Purpose Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Organize your scrubber modules by their intended purpose to maintain a clean and manageable codebase. This example illustrates separate modules for user comments and blog content. ```elixir # app/scrubbers/user_comments.ex defmodule MyApp.Scrubbers.UserComments do use HtmlSanitizeEx, extend: :basic_html # ... end # app/scrubbers/blog_content.ex defmodule MyApp.Scrubbers.BlogContent do use HtmlSanitizeEx, extend: :html5 allow_tag_with_these_attributes("style", ["type", "media"]) # ... end ``` -------------------------------- ### Extend a Custom Scrubber with HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/main.md You can extend a previously defined custom scrubber by referencing its module name in the `extend:` option. This example extends `MyProject.MyScrubber` to add support for the `data-level` attribute on `

` tags. ```elixir defmodule MyProject.MoreRules do use HtmlSanitizeEx, extend: MyProject.MyScrubber allow_tag_with_these_attributes("p", ["data-level"]) end ``` -------------------------------- ### Define Scrubbers as Modules Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Always define custom scrubbers as modules for better organization and reusability. This example shows how to define a scrubber module and then use it to sanitize HTML content. ```elixir defmodule MyApp.Scrubbers.UserContent do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("div", ["class"]) end # Use it MyApp.Scrubbers.UserContent.sanitize(html) ``` -------------------------------- ### Document Security Implications Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Clearly document any security implications or warnings associated with your scrubber configurations. This example highlights the allowance of `iframe` tags with a warning about `src` restrictions. ```elixir defmodule MyApp.Scrubbers.UGC do use HtmlSanitizeEx, extend: :html5 # WARNING: Allows iframe, but src restricted to https only # Ensure origin validation is enforced separately allow_tag_with_uri_attributes("iframe", ["src"], ["https"]) end ``` -------------------------------- ### Define Custom HTML Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md Create a custom scrubber to precisely control allowed HTML tags, attributes, and URI schemes. This example allows `p`, `h1` tags, and `a` tags with `href` attributes restricted to `https` and `mailto` schemes. ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx allow_tag_with_these_attributes("p", []) allow_tag_with_these_attributes("h1", []) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) end ``` -------------------------------- ### Extend Custom Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md Extend a previously defined custom scrubber to add more functionality. This example extends `MyProject.MyScrubber` to allow `class` attributes on `p` tags. ```elixir defmodule MyProject.MyOtherScrubber do use HtmlSanitizeEx, extend: MyProject.MyScrubber allow_tag_with_these_attributes("p", ["class"]) end ``` -------------------------------- ### Sanitize HTML with Protocol-Relative Links Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/uri-scrubber.md Sanitizes HTML content, ensuring that protocol-relative links are preserved correctly. This example demonstrates the output when a link with a protocol-relative URL is processed. ```elixir HtmlSanitizeEx.basic_html("link") # => "link" ``` -------------------------------- ### Extend Built-in Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md Extend an existing built-in scrubber, such as `:basic_html`, to add support for additional tags or attributes. This example extends `:basic_html` to allow `small` tags. ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("small", []) end ``` -------------------------------- ### HtmlSanitizeEx.__using__ Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/main.md The `__using__` macro is used with `use HtmlSanitizeEx` to create custom scrubber modules. It sets up the module as a scrubber, imports necessary macros, and handles CDATA sections, HTML comments, and optional extension of existing scrubbers. ```APIDOC ## HtmlSanitizeEx.__using__(opts \ []) ### Description This is a macro used with `use HtmlSanitizeEx` to create custom scrubber modules. It automatically: 1. Sets up the module as a scrubber with `@behaviour HtmlSanitizeEx.Scrubber` 2. Imports meta-programming macros from `HtmlSanitizeEx.Scrubber.Meta` 3. Removes CDATA sections before scrubbing 4. Strips HTML comments 5. Optionally extends an existing scrubber via the `extend:` option The `extend:` option accepts atoms (`:basic_html`, `:html5`, `:markdown_html`, `:strip_tags`, `:noscrub`) or custom scrubber module names. When extending, the new scrubber inherits all rules from the parent and can add additional rules. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **opts** (keyword list) - Optional - Macro options; supports `extend:` to inherit from existing scrubbers ### Request Example ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx allow_tag_with_these_attributes("p", ["class"]) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) end MyProject.MyScrubber.sanitize("

Hello

") # => "

Hello

" ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Blocking Attributes Starting With Entities Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/uri-scrubber.md The scrubber blocks attributes that start with an entity reference to prevent encoded malicious data. This is useful for preventing a class of encoded XSS attacks. ```elixir # Attribute starting with entity HmSanitizeEx.Scrubber.URI.scrub_attribute("img", {"src", "&malicious..."}, ["http", "https"]) # => nil ``` -------------------------------- ### Debug Sanitization Process Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/errors.md Shows how to use the parser directly to inspect the HTML tree and how to create a custom scrubber to debug the sanitization of each node. Useful for understanding unexpected sanitization results. ```elixir # Inspect what the parser sees html = "

text

" tree = HtmlSanitizeEx.Parser.parse(html) IO.inspect(tree) # => {"p", [], ["text"]} # Inspect what a scrubber does with each node defmodule MyDebugScrubber do use HtmlSanitizeEx def scrub(node) do IO.inspect(node, label: "scrubbing") super(node) end allow_tag_with_these_attributes("p", []) end MyDebugScrubber.sanitize("

text

") # Prints: scrubbing: {"p", [], ["text"]} # => "

text

" ``` -------------------------------- ### scrub/2 Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber.md Main entry point for sanitization. Handles nil and empty input gracefully, then orchestrates the scrubbing pipeline. ```APIDOC ## Function: `scrub/2` ### Description Sanitizes an HTML string using a specified scrubber module. Handles nil and empty input by returning an empty string. ### Function Signature ```elixir def scrub(html :: String.t(), scrubber_module :: atom()) :: String.t() ``` ### Parameters #### Parameters - **html** (String) - HTML string to sanitize, or nil/empty string. - **scrubber_module** (atom) - Module implementing the Scrubber behavior. ### Return Type `String.t()` — Sanitized HTML output. ### Example ```elixir HtmlSanitizeEx.Scrubber.scrub("

hello

", HtmlSanitizeEx.Scrubber.BasicHTML) # => "

hello

" ``` ``` -------------------------------- ### Get Linebreak Replacement Bytes Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/parser.md Returns the byte sequence used for preserving linebreaks during HTML parsing. This is an internal helper function. ```elixir def replacement_for_linebreak() :: list ``` -------------------------------- ### Get Tab Replacement Bytes Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/parser.md Returns the byte sequence used for preserving tabs between HTML tags during parsing. This is an internal helper function. ```elixir def replacement_for_tab() :: list ``` -------------------------------- ### Get Space Replacement Bytes Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/parser.md Returns the byte sequence used for preserving spaces between HTML tags during parsing. This is an internal helper function. ```elixir def replacement_for_space() :: list ``` -------------------------------- ### Basic HtmlSanitizeEx Usage Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Use this macro to configure HtmlSanitizeEx at the module level. The `extend` option allows inheriting rules from predefined scrubbers. ```elixir use HtmlSanitizeEx, opts ``` -------------------------------- ### Create a Custom Scrubber in Elixir Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/README.md Shows how to define a custom scrubber module in Elixir using HtmlSanitizeEx, extending existing configurations and defining allowed tags with specific attributes and URI schemes. ```elixir defmodule MyApp.MyScrubber do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("div", ["class"]) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) end MyApp.MyScrubber.sanitize(html) ``` -------------------------------- ### Meta-Macros for Custom Scrubbers Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/INDEX.md Macros to assist in defining custom scrubber behaviors. ```APIDOC ## HtmlSanitizeEx.allow_tag_with_these_attributes/2 ### Description Macro to allow a specific tag with a predefined list of attributes. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` ```APIDOC ## HtmlSanitizeEx.allow_tag_with_any_attributes/1 ### Description Macro to allow a specific tag with any attributes. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` ```APIDOC ## HtmlSanitizeEx.allow_tag_with_uri_attributes/3 ### Description Macro to allow a specific tag with attributes that should contain URIs. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` ```APIDOC ## HtmlSanitizeEx.allow_tag_with_this_attribute_values/3 ### Description Macro to allow a specific tag with a specific attribute that must have one of the provided values. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` ```APIDOC ## HtmlSanitizeEx.remove_cdata_sections_before_scrub/0 ### Description Macro to configure the scrubber to remove CDATA sections before scrubbing. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` ```APIDOC ## HtmlSanitizeEx.strip_comments/0 ### Description Macro to configure the scrubber to strip HTML comments. ### Location `use HtmlSanitizeEx` ### File [scrubber-meta.md](api-reference/scrubber-meta.md) ``` -------------------------------- ### Sanitize HTML with HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/README.md Demonstrates how to use HtmlSanitizeEx to strip all tags, allow basic formatting, or sanitize HTML5 with XSS protection. ```elixir # Strip all tags HtmlSanitizeEx.strip_tags("

Hello

") # => "Hello evil" # Allow basic formatting HtmlSanitizeEx.basic_html("

Title

Content

") # => "

Title

Content

" # Allow HTML5 with XSS protection HtmlSanitizeEx.html5("

Content

") # => "

Content

" ``` -------------------------------- ### HTML5 Scrubbing with CSS Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Demonstrates how the HTML5 scrubber automatically applies CSS scrubbing to style attributes, removing potentially malicious content. ```elixir HtmlSanitizeEx.html5("
text
") # => "
text
" ``` ```elixir HtmlSanitizeEx.html5("

x

") # => "

x

" ``` -------------------------------- ### Traverse HTML Tree with Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md Demonstrates how to use the `traverse/2` function to process an HTML tree with a custom scrubber module that removes class attributes. ```elixir tree = {"p", [{"class", "intro"}], ["Hello ", {"b", [], ["world"]}]} # Traverse with a scrubber that removes class attributes result = HtmlSanitizeEx.Traverser.traverse(tree, MyStripClassesScrubber) # Result: {"p", [], ["Hello ", {"b", [], ["world"]}]} ``` -------------------------------- ### Parse and Convert HTML Tree Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/errors.md Demonstrates correct usage of parsing HTML into a tree structure and then converting it back to HTML. This is the expected workflow for normal operation. ```elixir # This shouldn't happen in normal use, but if you manually construct # malformed trees and pass them to to_html/1: HtmlSanitizeEx.Parser.to_html("invalid") # May produce unexpected output; the function expects structured trees # Correct usage: tree = HtmlSanitizeEx.Parser.parse("

text

") HtmlSanitizeEx.Parser.to_html(tree) # => "

text

" ``` -------------------------------- ### Add HtmlSanitizeEx Dependency Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Include HtmlSanitizeEx and its dependency Mochiweb in your project's mix.exs file. Ensure you are using compatible Elixir and OTP versions. ```elixir defp deps do [ {:html_sanitize_ex, "~> 1.5"}, # html_sanitize_ex depends on: {:mochiweb, "~> 2.15 or ~> 3.1"} ] end ``` -------------------------------- ### Define Custom Scrubber with HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/CHANGELOG.md Use `HtmlSanitizeEx` to define a custom scrubber. This allows you to specify allowed tags and their attributes. A `sanitize/1` function is automatically generated in the module. ```elixir defmodule MyScrubber do use HtmlSanitizeEx allow_tag_with_these_attributes("p", ["title"]) end ``` -------------------------------- ### No Scrubbing (Testing) Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md The `noscrub/1` function is primarily intended for testing purposes and does not perform any sanitization on the input HTML. ```elixir HtmlSanitizeEx.noscrub(html) ``` -------------------------------- ### Extend BasicHTML Scrubber with Custom Rules Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Define a custom scrubber module by extending an existing one, such as `:basic_html`, and add specific tag allowlisting rules. ```elixir defmodule MyProject.CustomScrubber do use HtmlSanitizeEx, extend: :basic_html allow_tag_with_these_attributes("div", ["class"]) end ``` -------------------------------- ### HTML5 Sanitization with CSS Scrubbing Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Demonstrates how HtmlSanitizeEx automatically applies CSS scrubbing when sanitizing HTML5 content, specifically targeting the `style` attribute. ```APIDOC ## HtmlSanitizeEx.html5 ### Description Sanitizes HTML5 content, automatically applying CSS scrubbing to style attributes to remove potentially malicious CSS properties or values. ### Usage ```elixir HtmlSanitizeEx.html5("
text
") # => "
text
" HtmlSanitizeEx.html5("

x

") # => "

x

" ``` ``` -------------------------------- ### Define Custom Scrubber Rules Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber-meta.md Use this pattern to define a custom scrubber module. Specify allowed tags, attributes, and URI attributes. The `sanitize/1` function is automatically generated. ```elixir defmodule MyProject.MyScrubber do use HtmlSanitizeEx # Remove CDATA and comments (automatic via use) # remove_cdata_sections_before_scrub() # strip_comments() # Define allowed tags and attributes allow_tag_with_these_attributes("p", ["class", "id"]) allow_tag_with_uri_attributes("a", ["href"], ["https", "mailto"]) allow_tag_with_any_attributes("span") # Result: sanitize/1 is automatically generated end ``` -------------------------------- ### Scrubbing Blocked CSS with Unknown Properties Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Demonstrates the blocking of unknown or non-standard CSS properties by the scrubber. ```elixir # Blocked: unknown properties HtmlSanitizeEx.Scrubber.CSS.scrub( "color: red; -webkit-filter: blur(20px); opacity: 0.5" ) # => "color: red; opacity: 0.5" ``` -------------------------------- ### Quick HTML Sanitization with Built-in Scrubbers Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/INDEX.md Use built-in scrubbers for quick sanitization tasks. Choose from removing all tags, allowing basic formatting, or enabling HTML5 with XSS protection. ```elixir # Remove all tags HtmlSanitizeEx.strip_tags(user_html) ``` ```elixir # Allow basic formatting HtmlSanitizeEx.basic_html(user_html) ``` ```elixir # Allow HTML5 with XSS protection HtmlSanitizeEx.html5(user_html) ``` -------------------------------- ### High-level vs. Low-level Traversal in HtmlSanitizeEx Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md Demonstrates the recommended high-level `scrub/2` function and the lower-level `traverse/2` function for custom HTML sanitization. The high-level function is generally preferred for its simplicity and integrated preprocessing. ```elixir # High-level (recommended) result = HtmlSanitizeEx.Scrubber.scrub(html, MyModule) # Low-level (if needed) tree = HtmlSanitizeEx.Parser.parse(html) scrubbed = HtmlSanitizeEx.Traverser.traverse(tree, MyModule) result = HtmlSanitizeEx.Parser.to_html(scrubbed) ``` -------------------------------- ### Allowed CSS Color Formats Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Demonstrates the accepted formats for specifying colors in CSS, including Hex, RGB, and named colors. ```css #FF0000, #FFF, #000000 ``` ```css rgb(255,0,0), rgb(100%, 50%, 50%) ``` ```css red, blue, transparent ``` -------------------------------- ### Handle Empty or Nil Input Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/errors.md All scrubber functions safely return an empty string when provided with nil or empty input. This ensures predictable behavior for missing data. ```elixir HtmlSanitizeEx.basic_html(nil) # => "" HtmlSanitizeEx.basic_html("") # => "" HtmlSanitizeEx.strip_tags(nil) # => "" ``` -------------------------------- ### Traverse Special Tokens Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md Demonstrates the traversal of special tokens like comments and doctypes, which are typically stripped by default. ```elixir token = {:comment, ["this is a comment"]} result = HtmlSanitizeEx.Traverser.traverse(token, BasicHTML) # => "" (or stripped by default) ``` -------------------------------- ### Strip Everything Not Covered (Deprecated) Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber-meta.md The `strip_everything_not_covered/0` macro is deprecated and no longer necessary as the compiler automatically handles stripping unallowed tags and attributes. It is included for backward compatibility. ```elixir defmacro strip_everything_not_covered() ``` -------------------------------- ### Scrubber Behavior: before_scrub/1 Callback Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber.md Implement this callback to preprocess HTML before it's parsed into a tree structure. Use it to remove or escape problematic content like CDATA sections or PHP tags. ```elixir @callback before_scrub(html :: String.t()) :: String.t() ``` -------------------------------- ### Traverse Text Nodes Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/traverser.md Shows how text nodes are passed to the scrubber's `scrub/1` callback. Handles both content and empty strings. ```elixir HtmlSanitizeEx.Traverser.traverse("hello world", BasicHTML) # => "hello world" HtmlSanitizeEx.Traverser.traverse("", BasicHTML) # => "" ``` -------------------------------- ### scrub/1 Callback Signatures Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/types.md The scrub/1 callback is overloaded to accept different input types: element nodes (tuples), token nodes (tuples), and text content (strings). ```elixir @callback scrub(node_with_children :: tuple) :: tuple @callback scrub(token :: tuple) :: tuple @callback scrub(text :: String.t()) :: String.t() ``` -------------------------------- ### Test Custom Scrubbers with Elixir Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/errors.md This Elixir test suite demonstrates how to verify custom scrubber behavior against various HTML inputs, including XSS payloads and attribute stripping. ```elixir defmodule MyApp.ScrubberTest do use ExUnit.Case test "strips scripts" do html = "

text

" assert MyApp.Scrubber.sanitize(html) == "

text

" end test "allows basic formatting" do html = "

bold italic

" assert MyApp.Scrubber.sanitize(html) == "

bold italic

" end test "blocks javascript URLs" do html = "click" assert MyApp.Scrubber.sanitize(html) == "click" end test "handles nil" do assert MyApp.Scrubber.sanitize(nil) == "" end end ``` -------------------------------- ### Scrubber Behavior Callbacks Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/INDEX.md Callbacks that can be implemented to define custom scrubbing logic. ```APIDOC ## HtmlSanitizeEx.Scrubber.before_scrub/1 ### Description Callback executed before the main scrubbing process begins. ### Signature `(String) → String` ### File [scrubber.md](api-reference/scrubber.md) ``` ```APIDOC ## HtmlSanitizeEx.Scrubber.scrub/1 ### Description Callback for the main scrubbing logic, operating on nodes, tokens, or text. ### Signature `(node | token | text) → same` ### File [scrubber.md](api-reference/scrubber.md) ``` ```APIDOC ## HtmlSanitizeEx.Scrubber.scrub_attributes/2 ### Description Callback to scrub attributes of an HTML element. ### Signature `(String, List) → List` ### File [scrubber.md](api-reference/scrubber.md) ``` ```APIDOC ## HtmlSanitizeEx.Scrubber.scrub_attribute/2 ### Description Callback to scrub a single attribute of an HTML element. ### Signature `(String, Tuple) → Tuple | nil` ### File [scrubber.md](api-reference/scrubber.md) ``` -------------------------------- ### Allow Basic HTML Elements Source: https://github.com/rrrene/html_sanitize_ex/blob/master/README.md Use `basic_html/1` to sanitize HTML by allowing only basic, safe HTML elements. This preserves essential formatting while removing potentially harmful tags like `" HmlSanitizeEx.basic_html(text) # => "

Hello World!

" ``` -------------------------------- ### Strip Unknown Keywords and Units from CSS Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Unrecognized keywords and units in CSS values are stripped by the scrubber. Valid values are retained. ```elixir HtmlSanitizeEx.Scrubber.CSS.scrub("color: unknowkeyword") # => "" (unknown keyword removed) ``` ```elixir HtmlSanitizeEx.Scrubber.CSS.scrub("width: 100unknownunit") # => "" (unknown unit removed) ``` ```elixir HtmlSanitizeEx.Scrubber.CSS.scrub("width: 100px; color: blue") # => "width: 100px; color: blue" (valid values kept) ``` -------------------------------- ### Internal Functions Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Details on internal helper functions used by the CSS scrubber. ```APIDOC ## Internal Functions ### `allowed_keyword?/1` ```elixir def allowed_keyword?(val :: String.t()) :: boolean() ``` Checks if a CSS value is in the allowed keywords list. Case-insensitive. ```elixir HtmlSanitizeEx.Scrubber.CSS.allowed_keyword?("red") # => true HtmlSanitizeEx.Scrubber.CSS.allowed_keyword?("RED") # => true HtmlSanitizeEx.Scrubber.CSS.allowed_keyword?("rgb(255,0,0)") # => false (rgb is a function, not a keyword) ``` ``` -------------------------------- ### Allow Tag with URI Attributes and Valid Schemes Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/configuration.md Configure a tag to allow specific URI attributes, ensuring that the URIs conform to a list of valid schemes. Useful for links and image sources. ```elixir allow_tag_with_uri_attributes(tag_name, uri_attrs, valid_schemes) ``` -------------------------------- ### Allowed CSS Keywords Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Lists common CSS keywords that are permitted. These are often used for properties like 'display', 'text-align', 'font-weight', etc. ```css auto, aqua, black, block, blue, bold, both, bottom, brown, center, collapse, dashed, dotted, fuchsia, gray, green, !important, italic, justify, left, lime, maroon, medium, middle, none, navy, normal, nowrap, olive, pointer, purple, red, right, solid, silver, teal, top, transparent, underline, white, yellow ``` -------------------------------- ### Scrubbing Mixed Safe and Unsafe CSS Values Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/css-scrubber.md Illustrates how the scrubber handles CSS properties with multiple values, keeping valid ones and discarding invalid ones. ```elixir # Mixed safe/unsafe values HtmlSanitizeEx.Scrubber.CSS.scrub( "width: 100px 200px; width: 100px" ) # => "width: 100px" # (first width has two values, only single values allowed; second width is valid) ``` -------------------------------- ### Allow relative URL with scrub_attribute/3 Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/uri-scrubber.md Demonstrates that `scrub_attribute/3` allows attributes with no scheme, such as relative URLs. This is important for maintaining links to internal pages or assets. ```elixir # No scheme - allowed (relative URL) HtmlSanitizeEx.Scrubber.URI.scrub_attribute("a", {"href", "/path/to/page"}, ["http", "https"]) # => {"href", "/path/to/page"} ``` -------------------------------- ### strip_everything_not_covered() Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/scrubber-meta.md Deprecated macro that previously generated default `scrub_attribute/1` fallbacks. It is no longer necessary as the compiler now automatically strips tags and attributes not explicitly allowed. It is included for backward compatibility. ```APIDOC ## strip_everything_not_covered() ### Description **Deprecated.** This macro is no longer necessary. The compiler automatically strips tags and attributes not explicitly allowed. Included for backwards compatibility with older scrubber definitions. ### Return Type Generates default `scrub_attribute/1` fallbacks. ``` -------------------------------- ### Sanitize HTML with HTML5 Scrubber Source: https://github.com/rrrene/html_sanitize_ex/blob/master/_autodocs/api-reference/built-in-scrubbers.md Use the `html5/1` function for the most permissive HTML sanitization, allowing most HTML5 elements and attributes while blocking dangerous content. This is suitable for general-purpose HTML sanitization where a wide range of HTML5 features are expected. ```elixir html = """

Title

Blue text

""" HtmlSanitizeEx.html5(html) # => all legitimate HTML5 preserved HtmlSanitizeEx.html5("") # => "" HtmlSanitizeEx.html5("

text

") # => "

text

" ```