"safe" templating in Elixir

I’m writing an application in Elixir where users should be able to create templates (which later get rendered into HTML and then into PDF).
I’m currently working with EEx, however there’s two problems to tackle:

  • code execution (this one I know how to handle, since EEx can compile to a quoted expression which I can walk to detect unauthorized calls)
  • atom generation

The second one is more problematic, EEx generates atoms for the variables used in the template, and we all know that having users create atoms is a BAD idea.

I had submitted a PR (which will appear in 1.13) to allow me passing in a method that is called when creating atoms and instead output strings, however turns out that in the tokenization step EEx generates am atom and then returns it as a string (but the atom is created nonetheless).

The only way to avoid this would be passing in a parser_options to the tokenizer call which I think isn’t even public API (:elixir_tokenizer) so I’m guessing a PR to add options to that will be rejected (José if you’re reading this and I’m wrong let me know!).

Long story short, anyone have experience in this, suggestions or ideas? I’d want to have user supplied templates, at runtime to generate HTML.

EEx is currently problematic due to atoms being created while compiling.

EDIT: I’m currently on mobile but when I’m home I’ll link the exact code that causes problems along with some tests and examples :slight_smile:

EDIT 2: The exact line that’s generating atoms is elixir/tokenizer.ex at master · elixir-lang/elixir · GitHub if I could pass in a static_atoms_encoder option (see Code — Elixir v1.12.2) I could use EEx templates without it generating any atoms at all (I verified this with a locally modified EEx library).

2 Likes

There is no way to make EEx safe. Instead you should use another template library that will not also be easier for users, but also will be more secure, for example:

2 Likes

This would be for an internal tool and the people using it would have experience with Elixir, so the EEx syntax would already be familiar. Honestly the only real problem I’m still facing is the generation of atoms and I’d really like to solve it if possible (without having an entire modified copy of the EEx source code in my application (even if that’s just 4-5 files).

Regardless I’ll definitely take a look at the libraries you linked, thanks a bunch!

There is no way to make any templating safe, not even markdown. However, you can sanitize the resulting html with [html_sanitize_ex | Hex]

Turned out I did not read the original post carefully. I was thinking about safe to embedding user content on your website and the post was talking about safe to run elixir flavored template in the application. Then I have no idea; it is not something I dare to try.

I’m quite sure markdown is safe if you disable its HTML support.

With Markdown the “unsafe” part is potential XSS attacks, but in this case the internal tool will just render the HTML in a headless browser (that doesn’t keep any state) to render a PDF.
The HTML here is not much of a security concern, but that’s just this specific case :slight_smile:

my experiences with solid have been very good. It has been able to do everything that I want so far, including customizing some of the available template functions.

Giving users direct access to eex is probably not the best idea? Solid is a liquid template implementation, which was designed to run code from potentially hostile users.

2 Likes