tags:

views:

1295

answers:

6

So Lua seems ideal for implementing secure "user scripts" inside my application.

However, most examples of embedding lua seem to include loading all the standard libraries, including "io" and "package".

So I can exclude those libs from my interpreter, but even the base library includes the functions "dofile" and "loadfile" which access the filesystem.

How can I remove/block any unsafe functions like these, without just ending up with an interpreter that doesn't even have basic stuff like the "ipairs" function?

+1  A: 

You can use the lua_setglobal function provided by the Lua API to set those values in the global namespace to nil which will effectively prevent any user scripts from being able to access them.

lua_pushnil(state_pointer);
lua_setglobal(state_pointer, "io");

lua_pushnil(state_pointer);
lua_setglobal(state_pointer, "loadfile");

...etc...
Amber
A: 

You can override (disable) any Lua function you want and also you can use metatables for more control.

Nick D
Metatables can be bypassed via rawget() and should not be used for security, only for convenience.
Amber
thanks for mentioning that.
Nick D
Can't you override rawget if you want?
RCIX
RCIX, you can do it. You have the *freedom* to do almost anything in Lua :-)
Nick D
You *could* override rawget, but that would break non-malicious metatable functionality as well, and is not an ideal solution.
Amber
+11  A: 

You can set the function environment that you run the untrusted code in via setfenv(). Here's an outline:

local env = {}
setfenv(untrusted_function, env)
pcall(untrusted_function)

The function can only access what is in its environment. So you can then explicitly add in the functions that you want the untrusted code to have access to (whitelist).

See Lua Sandboxes for an example and more information on lua sandboxing.

Karl Voigtland
+1  A: 

One of the easiest ways to clear out undesirables is to first load a Lua script of your own devising, that does things like:

load = nil
loadfile = nil
dofile = nil

Alternatively, you can use setfenv to create a restricted environment that you can insert specific safe functions into.

Totally safe sandboxing is a little harder. If you load code from anywhere, be aware that precompiled code can crash Lua. Even completely restricted code can go into an infinite loop and block indefinitely if you don't have system for shutting it down.

John Calsbeek
You don't actually have to load a Lua script to nil things out - you can use the Lua API functions that I mentioned in my answer to nil out the globals from outside of Lua.
Amber
Indeed, but this is in some ways easier, hence the "easiest" qualification.
John Calsbeek
+4  A: 

The Lua live demo contains a (specialized) sandbox. The source is freely available.

lhf
+1  A: 

This question may be helpful:

http://stackoverflow.com/questions/966162/best-way-to-omit-lua-standard-libraries

Nick