[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Using Lua for config files
- From: Sean Conner <sean@...>
- Date: Thu, 19 Dec 2013 12:24:50 -0500
It was thus said that the Great Steve Litt once stated:
> On Wed, 18 Dec 2013 19:43:47 -0500
> Rena <hyperhacker@gmail.com> 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.
>
> I see other problems, the biggest of which is that, to me, Lua config
> files represent a huge compromise of encapsulation. The purpose of a
> config file is to enable customization of the program, but in most
> cases it's not to make the program completely maleable to the user, nor
> to introduce opportunities for weird, hard to find bugs.
>
> I can see Lua as config in games, where you might want to introduce a
> whole new behavior after the fact. But not in the average program,
> where you're setting files, directories, names, and choices between
> finite alternatives.
So I have an application [1] that uses Lua just for the configuration [2]
and yes, it has the typical files and directories stuff:
name = "The Boston Diaries"
basedir = "/home/spc/web/sites/boston.conman.org/journal"
webdir = "/home/spc/web/sites/boston.conman.org/htdocs"
url = "http://boston.conman.org/"
author = { name = "Sean Conner" , email = "sean@conman.org" }
startdate = "1999/12/4"
templates =
{
{
template = "html/regular",
output = webdir .. "/index.html",
items = "7days",
reverse = true
},
{
template = "rss",
output = webdir .. "/bostondiaries.rss",
items = 15,
reverse = true
},
{
template = "atom",
output = webdir .. "/index.atom",
items = 15,
reverse = true
}
}
But I was able to rip out quite a bit of code because now I could do stuff
like:
-- -------------------------------------------------------------
-- Custom locale to get "Debtember" without special code in the
-- program
-- -------------------------------------------------------------
os = require("os")
os.setlocale("en_SPC")
and even set resource limits:
-- ---------------------------------------------------------------
-- process limits added because an earlier version of the code
-- actually crashed the server it was running on, due to resource
-- exhaustion.
-- ---------------------------------------------------------------
process = require("org.conman.process")
process.limits.hard.cpu = "10m"
process.limits.hard.core = 0
process.limits.hard.data = "20m"
Sure, I could have done:
system =
{
locale = "en_SPC",
cpu = "10m",
core = 0,
data = "20m"
}
and have a bunch of code pull these values out and call the appropriate
routines, but the code *already exists* in Lua to set the locale and to set
resource limits [3]; why duplicate that in the main application?
I understand about the security threats ("ARBITRARY CODE IN A CONFIG FILE?
ARE YOU MAD?") but the flexibility to run code *in my case* results in less
code in my application and the ability to tailer the environment suit my
needs (like limited the size of the data segment to 20 megabytes [4])
without having to modify the source code of the application. And if someone
can modify my config file I have bigger issues to worry about (if they can
modify my config file, I have to assume they can modify any file).
I was discussing this with a list member privately (and unless they pipe
up, I won't mention names) and I mentioned that LuaRocks uses Lua as a
configuration file. Rockspecs are Lua files. And yes, I can provide a
rockspec that goes into an infinite loop. Maybe even crash Lua but given
that the rockspec is loaded into an empty Lua environment, I can't see how
one could break out and execute arbitrary code [5]. And frankly, I haven't
seen anyone express concern that rockspecs are Lua code.
-spc (Over time, quite a few configuration formats become Turing complete
because people want it. Look at sendmail.cf for example ... )
[1] A blogging engine (https://github.com/spc476/mod_blog) for running
my blog (http://boston.conman.org/)
[2] The blogging engine is written in C. It was written fourteen years
ago. Back then I had this ad-hoc configuration file format. I
decided to switch over to Lua a few years ago.
[3] https://github.com/spc476/lua-conmanorg/blob/master/src/process.c
[4] The crash happened referenced in the comments happened very early on
and was due to resource exhaustion becuase of a bug in the code (it
happens). The resource limiting code was hacked in at that time.
[5] http://lua-users.org/lists/lua-l/2013-09/msg00393.html
But note that the environment isn't empty. I have looked at Peter
Cawley's past experiments at breaking out of Lua jails, and in each
case, the "jail" wasn't completely empty---there was some function
he had access to that he could exploit to escape or run arbitrary
code. [6]
[6] About the worse that can happen with an empty Lua environment is the
process crashing. Bad, but it's not arbitrary code execution.