Is `Meta.parse` safe to use on unsanitized external input?

The question might be naive, almost disrespectful, but better safe than sorry: Does Meta.parse use any eval-like calls or anything else that would make it dangerous to use on potentially malicious input?

5 Likes

Afaiu it is not supposed to pop a shell, unlike e.g. eval or deserialization.

On the other hand, afaiu Meta.parse is not hardened as a security boundary either (e.g. regularly run through AFL or libfuzzer). Any core people who happen to know better, please correct me here.

So I strongly recommend against it. What is your application? Maybe there is a better way.

4 Likes

Here is what I want to use it for: parsing a user provided string (of size that is enforced to be relatively small), ensuring that it contains only some very simple white-listed constructs (only “array literal of whitelisted constructors”), and then calling eval on the validated AST.

That is an admittedly annoying situation to be in.

A low-effort solution (if viable) would be on the deployment side: Ensure that you can live with people popping a shell occasionally. Put it into a virtual machine that is isolated from your network (and has throttled resource use) and restore from image whenever it crashes or you notice that you got powned. Docker is not a VM, and privilege escalation exploits are too common to trust user separation. There are super cheap virtual private servers one can use.

That approach depends on your application not needing access to valuable data (like e.g. personal data or a user database or valuable ssh or ssl keys), i.e. only really works if you want to semi-publically host a convenient calculator for something (e.g. for lower user threshold than “install julia, install these packages”).

1 Like

What about parsing Json? That might be a better approach since that would ensure they don’t pass in anything bad.

2 Likes

I do not think json (or something like it) would work for me, as the goal is to demo a Julia library (with an extremely restricted whitelisted set of permitted constructs in the input code). If the starting point is Julia-like code, parsing it myself into something like json (which is then used in a safer manner) does not sound much safer than using Meta.parse.

This is correct: it’s safe in principle but not a hardened function, so it’s possible that it can be attacked with a malicious malformed input. If someone wanted to feed (literally) random strings into Meta.parse and see what happens, it would be a good first step to help harden it against attacks.

3 Likes

Well, while true try Meta.parse(transcode(String, rand(UInt8,20))) catch end end does not do anything interesting, so I guess now is a good time to learn how to use libfuzzer. Seems like a fun distraction.

1 Like

See also GitHub - cmcaine/Sandboxes.jl which provides sandboxed_eval().

1 Like

Which Julia functions have been fuzzed?

Here is a naive attempt at fuzzing using libFuzzer. Advice would (as always) be appreciated Fuzzing Julia functions (for security hardening)

1 Like