Safety
View SourceMDEx employs 4 mechanisms to handle safety: omitting), escaping, sanitizing, and unsafe rendering.
TL;DR is if you trust the input then just use render: [unsafe: true]
option to render raw HTML,
otherwise consider using render: [unsafe: true], sanitize: MDEx.default_sanitize_options()
to be on the safe side.
Omitting/Removing unsafe content (default)
For security reasons, MDEx does not render raw HTML by default:
iex> MDEx.to_html!("<h1>Hello</h1>")
"<!-- raw HTML omitted -->"
But that's not very useful for most cases, so you have a few other options:
Escape
The most basic is render raw HTML but escape it:
iex> MDEx.to_html!("<h1>Hello</h1>", render: [escape: true])
"<h1>Hello</h1>"
Sanitize
But if the input is provided by external sources, it might be a good idea to sanitize it:
iex> MDEx.to_html!("<a href=https://elixir-lang.org>Elixir</a>", render: [unsafe: true], sanitize: MDEx.default_sanitize_options())
"<p><a href=\"https://elixir-lang.org\" rel=\"noopener noreferrer\">Elixir</a></p>"
Note that you must pass the unsafe: true
option to first generate the raw HTML in order to sanitize it.
It does clean HTML with a conservative set of defaults that works for most cases, but you can overwrite those rules for further customization.
For example, let's modify the link rel attribute
to add "nofollow"
into the rel
attribute:
iex> MDEx.to_html!("<a href=https://someexternallink.com>External</a>", render: [unsafe: true], sanitize: [link_rel: "nofollow noopener noreferrer"])
"<p><a href=\"https://someexternallink.com\" rel=\"nofollow noopener noreferrer\">External</a></p>"
In this case the default rule set is still applied but the link_rel
rule is overwritten.
Unsafe
If those rules are too strict and you really trust the input, or you really need to render raw HTML, then you can just render it directly without escaping nor sanitizing:
iex> MDEx.to_html!("<script>alert('hello')</script>", render: [unsafe: true])
"<script>alert('hello')</script>"