A simple sandboxing mechanism for evaluating Julia code in a restricted environment. You might want to use this if:
- You want to evaluate untrusted code and restrict what it can do
- You want to define a simpler version of Julia for teaching something or as a DSL
- Make a bare module, M
- Eval the desired interface into M
- Check an expr E to eval in M
- White or blacklist certain Expr heads and types
- Rewrite symbols that are equal to symbols in Core and
:ccall
(so the only available symbols are those that have been eval'd in)- This step unnecessary if Julia later supports more bare baremodules (https://discourse.julialang.org/t/even-more-bare-baremodule/56156/)
A valid alternative method might be to use a compiler pass like Cassette, but I don't think we need to.
This isn't implemented yet, I'm still deciding. For now, check the tests to see how to use it.
@sandboxed module M
# Your safe interfaces here
end
sandboxed_eval(M, expr)
sandboxed_include(M, file)
# Evaluate code without sandboxing, if you need to
@eval M unsandboxed_expr
It might be appropriate for us to warn if the user imports any code with anything other than using X: something_safe
.
Users will need to be cautious of eval
available on most module objects, for example.
If you need many sandboxes:
sandbox() = eval(:(@sandboxed module M ... end))
Probably want to provide a string interface for REPLs and an easy interface for disabling bits of Julia, seeing as I've done that work and it might be useful for others. Or maybe I should just provide an example and suggest they copy it to start them off, idk.
It would be useful if users could easily use the safe parts of Base
.
map
, filter
, arithmetic, etc, are probably safe :)
- eval'ing extra properties onto
Core
after a sandbox has started