fireproofsocks
Testing whether a string contains valid Elixir code?
This is admittedly a strange use-case, but I’ve been working on writing a Handlebars parser in Elixir and one of the gotchas is that you don’t want clever users injecting random Elixir code into your templates.
For example, this is a nice and benign Handlebars template:
{{#if some_variable}}
Hello there!
{{/if}}
– it would get safely converted to EEx and no harm is done.
However, if some clever nefarious user provided a template like this:
{{#if File.write!("/path/to/webroot/index.html", "All your base belong to us!")}}
Hello there!
{{/if}}
then I want to be able to catch it. It’s tough however… parentheses are optional, legitimate values may be quoted or not. The only thing I can think of is checking the input (File.write!("/path/to/webroot/index.html", "All your base belong to us!") in this case) to see if it
a) begins with a capital letter (i.e. if it might be a module name) or
b) begins with a colon (which would denote some Erlang code)
Does anyone have any other ideas? Many thanks!
Most Liked
benwilson512
Converting anything from untrusted users into Elixir code that you then execute is doomed to be a security issue. There will always be some fancy combination of stuff that isn’t technically Elixir code that, when the template comes together, creates valid elixir code that is then executed. I’d use an Elixir library that evaluates mustache templates, instead of converting it to Elixir.
jmbejar
Checking if a string contains “safe” Elixir code is a tough problem, but there are some tools in the language to play with.
If you have access to the some_variable part, the string containing the Elixir code to check, you can use Code.string_to_quoted/2 to get the AST representation of the code. This function will return an error when the code is not proper Elixir code. This is not executing the code itself, so it is safe to run (well, there is a limit in the number of atoms you can create, and the nodes of the AST will contain atoms, something to know beforehand).
You can use the AST form of the code to check which modules and functions are being called in the user-provided code. Unfortunately, this is not an easy process, because you also have to consider some tricks where modules are resolved at runtime (not being present on the static AST representation). If fact, it hard to get a fully secure solution unless you restrict much of the Elixir language (it may apply to your use case, tough).
I don’t want to use this reply to promote a personal project, but it is actually very related because the execution of untrusted Elixir code is at the heart of it. You can read it more about the decisions I made here: https://github.com/wyeworks/elixir_console#where-my-elixir-code-is-executed. I’m happy to keep discussing about it if you think it would make sense for your use case.
dimitarvp
This looks extremely hard and very error-prone.
You might be better off searching for a tool that converts your input to another format that is supported by Elixir.







