[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Using Lua for config files
- From: William Ahern <william@...>
- Date: Wed, 18 Dec 2013 17:20:34 -0800
On Wed, Dec 18, 2013 at 07:43:47PM -0500, Rena wrote:
> It's very tempting to write config files that are just Lua scripts that
> construct tables/strings and call some pre-defined functions. The only
> problem with this is that a faulty or malicious config file can do a lot
> more than a config file should be able to do.
>
> This is partially mitigated by not providing any functions in the
> environment that it doesn't need, but that doesn't prevent someone slipping
> "while true do end" or (if you provide the string library)
> ("x"):rep(100000000) into them. (And the latter won't be stopped by a debug
> hook counting instructions either.) The only way I know of to avoid this is
> to impose resource limits on the entire process, but that seems like
> overkill, and Lua doesn't provide a way to do that natively.
>
> Really, there's no need I can see for a config file to ever use a loop, so
> what if we could just ask Lua "load this file, but throw an error if it
> contains any loop instructions"? Or, what if we could load the file,
> string.dump it, and examine the bytecode to see if it has any loops?
>
> I don't really know enough about Lua bytecode to try such a thing. I think
> it'd be simple enough to scan for backward branches, but that wouldn't
> avoid creating a loop like:
> function f() f() end; f()
> or even chaining a few functions together to avoid simple detection. But
> config files usually shouldn't have any need to create functions, either...
>
> I think by disallowing loops and the creation of functions, and being
> careful what you provide in the environment, it could be safe to have your
> config files be Lua source files, and load them without any resource limits.
>
It will never be safe to load untrusted code, simply because it's naive to
assume that Lua will ever be without bugs. This last release fixed a couple
of issues that could have led to a crash or exploit using basic function
syntax, without access to any the base library.
Java's JVM was rigorously designed to allow for this kind of sandboxing, but
ultimately it proved insufficient because a perfect implementation was
impossible. Lua is substantially simpler, but as a security engineer I could
still never trust it to run completely untrusted code (i.e. code that might
be actively malicious).
At the end of the day, the Lua parser, virtual machine, and garbage
collector are non-trivial. And no amount of sandboxing can prevent malicious
code from exercising that code.