gavid

gavid

Can you break this "safe" interpreter?

I wanted to create a way to “safely” evaluate a string containing Elixir code. The code in the string should not be allowed to use any functions or modules (not even those from the Kernel e.g. defmodule/2).

Have I succeeded, or are there still ways to create a string that will allow the function to succeed while violating my criteria above?

  def safe_eval(code) when is_binary(code) do
      quoted_form = Code.string_to_quoted!(code, existing_atoms_only: true)
      Macro.postwalk(quoted_form, fn node ->
        if is_tuple(node) and (Kernel.elem(node, 0) in [:__aliases__]) do
          raise "Cannot use aliases or references to other modules"
        end
      end)
      {evaluated, _bindings} = Code.eval_string(code, [], %Macro.Env{})
      {"ok", evaluated}

  end

Most Liked

jhogberg

jhogberg

Erlang Core Team

Try "<<0::size(123456789123456789)>>" :slight_smile:

Why does it have to be Elixir code? If you can’t call any functions or modules then it sounds restricted enough that you could probably do what you want with a simple DSL instead, and writing an interpreter for a (say) small Lisp-like DSL doesn’t take very long.

adamu

adamu

jhogberg

jhogberg

Erlang Core Team

I guess it depends on the threat model, the underlying :erl_eval module wasn’t designed to be safe against a determined attacker: at the very least it’ll be possible for them to exhaust system resources.

If it’s just about guarding against accidental calls to other modules and the like, then I think a better approach would be to use the local/non-local function handler functionality in :erl_eval to filter calls, as nothing can sneak through that (as @hst337 pointed out, dynamic calls still sneak through yours). Code.eval_string/3 doesn’t expose this functionality (yet?) so it’ll be a bit of a slog to copy and modify Code.eval_string/3 + :elixir.eval_forms/4, but it can be done.

… but you might not have to if Dune is good enough, as pointed out by @adamu :slight_smile:

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52673 488
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement