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>"], [[[] | "&lt;"], "script" | "&gt;"]] | "</h1>"]}
iex> "#{content}"
"<h1>&lt;script&gt;</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>"], [[[] | "&lt;"], "script" | "&gt;"]] | "</h1>"]}
iex> "#{content}"
"<h1>&lt;script&gt;</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>&lt;script&gt;</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
[[], [[[] | "&lt;"], "script" | "&gt;"]]

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

Link to this function escape(content)

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.

Link to this function escape_to_binary(data)
escape_to_binary(String.t()) :: String.t()

Escapes the given HTML to string.

iex> EExHTML.escape_to_binary("foo")
"foo"

iex> EExHTML.escape_to_binary("<foo>")
"&lt;foo&gt;"

iex> EExHTML.escape_to_binary("quotes: \" & \'")
"quotes: &quot; &amp; &#39;"

iex> escape_to_binary("<script>")
"&lt;script&gt;"

iex> escape_to_binary("html&company")
"html&amp;company"

iex> escape_to_binary("\"quoted\"")
"&quot;quoted&quot;"

iex> escape_to_binary("html's test")
"html&#39;s test"
Link to this function escape_to_iodata(data)
escape_to_iodata(String.t()) :: iodata()

Escapes the given HTML to iodata.

iex> EExHTML.escape_to_iodata("foo")
"foo"

iex> EExHTML.escape_to_iodata("<foo>")
[[[] | "&lt;"], "foo" | "&gt;"]

iex> EExHTML.escape_to_iodata("quotes: \" & \'")
[[[[], "quotes: " | "&quot;"], " " | "&amp;"], " " | "&#39;"]
Link to this function javascript_variables(variables)

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.

Link to this macro sigil_E(arg, list) (macro)

This module adds ~E sigil for safe HTML escaped content.