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