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
Try "<<0::size(123456789123456789)>>" ![]()
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
Have you seen Dune - Sandbox for Elixir?
jhogberg
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 ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









