eex_html v1.0.0 EExHTML
Extension to Embedded Elixir (EEx), part of the standard library, that allows content to be safely embedded into HTML.
iex> title = "EEx Rocks!"
iex> content = ~E"<h1><%= title %></h1>"
%EExHTML.Safe{data: [[[[] | "<h1>"], "EEx Rocks!"] | "</h1>"]}
iex> "#{content}"
"<h1>EEx Rocks!</h1>"
iex> title = "<script>"
iex> content = ~E"<h1><%= title %></h1>"
%EExHTML.Safe{data: [[[[] | "<h1>"], [[[] | "<"], "script" | ">"]] | "</h1>"]}
iex> "#{content}"
"<h1><script></h1>"
Safe HTML
Escaping
The main responsibility of this library is to ensure safety when embedding content into HTML pages.
Any term that implements the String.Chars
protocol can be embedded but will be assumed unsafe.
iex> title = :"<script>"
iex> content = ~E"<h1><%= title %></h1>"
%EExHTML.Safe{data: [[[[] | "<h1>"], [[[] | "<"], "script" | ">"]] | "</h1>"]}
iex> "#{content}"
"<h1><script></h1>"
JavaScript
Including untrusted data inside any other JavaScript context is quite dangerous, as it is extremely easy to switch into an execution context with characters including (but not limited to) semi-colon, equals, space, plus, and many more, so use with caution. XSS Prevention Cheat Sheet
DONT DO THIS
~E\"\"\"
<script type="text/javascript">
console.log('Hello, ' + <%= name %>)
</script>
\"\"\"
Use javascript_variables/1
for injecting variables into any JavaScript environment.
DO THIS
~E\"\"\"
<%= javascript_variables name: "Cynthia" %>
<script type="text/javascript">
console.log('Hello, ' + name)
</script>
\"\"\"
Raw content
Data supplied by the user or other external source should never be considered safe. The assumption that user data is safe is the source of Cross-Site Scripting(XSS) attacks.
There some cases where data is safe and you want to use the raw content in a template.
iex> title = "<script>"
iex> content = ~E"<h1><%= raw title %></h1>"
%EExHTML.Safe{data: [[[[] | "<h1>"], "<script>"] | "</h1>"]}
iex> "#{content}"
"<h1><script></h1>"
Note content produced from a template is automatically considered safe
iex> title = "<script>"
iex> header = ~E"<h1><%= title %></h1>"
iex> page = ~E"<header><%= header %></header>"
iex> "#{page}"
"<header><h1><script></h1></header>"
EExHTML.Safe
Any struct can implement the EExHTML.Safe
protocol for custom behaviour when it is used in templates.
Engine
The EExHTML.Engine
implements the EEx.Engine
behaviour and can be used in EEx
functions.
iex> EEx.eval_string("<%= title %>", [title: "<script>"], engine: EExHTML.Engine).data
[[], [[[] | "<"], "script" | ">"]]
Link to this section Summary
Functions
Escape the HTML content derived from the given term
Escapes the given HTML to string
Escapes the given HTML to iodata
Safety inject server variables into a pages JavaScript
Mark some content as safe so that it can be used in a template
This module adds ~E
sigil for safe HTML escaped content
Link to this section Functions
Escape the HTML content derived from the given term.
The content is returned wrapped in an EExHTML.Safe
struct so it is not reescaped by templates etc.
Escapes the given HTML to string.
iex> EExHTML.escape_to_binary("foo")
"foo"
iex> EExHTML.escape_to_binary("<foo>")
"<foo>"
iex> EExHTML.escape_to_binary("quotes: \" & \'")
"quotes: " & '"
iex> escape_to_binary("<script>")
"<script>"
iex> escape_to_binary("html&company")
"html&company"
iex> escape_to_binary("\"quoted\"")
""quoted""
iex> escape_to_binary("html's test")
"html's test"
Escapes the given HTML to iodata.
iex> EExHTML.escape_to_iodata("foo")
"foo"
iex> EExHTML.escape_to_iodata("<foo>")
[[[] | "<"], "foo" | ">"]
iex> EExHTML.escape_to_iodata("quotes: \" & \'")
[[[[], "quotes: " | """], " " | "&"], " " | "'"]
Safety inject server variables into a pages JavaScript.
Mark some content as safe so that it can be used in a template.
Will check that content is an iolist or implements String.Chars
protocol.
This module adds ~E
sigil for safe HTML escaped content.