lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.