Sand Boxes |
|
The following is the simplest sandbox and one of the most restrictive:
-- make environment local env = {} -- run code under environment local function run(untrusted_code) local untrusted_function, message = loadstring(untrusted_code) if not untrusted_function then return nil, message end setfenv(untrusted_function, env) return pcall(untrusted_function) end -- test assert(run [[function f(x) return x^2 end; t={2}; t[1]=f(t[1])]])
Code in this sandbox can create variables in the sandbox environment, create values of primitive types (thereby allocating memory), and perform computations. There is no limit to memory usage and computation, so the untrusted code could still severely impact system performance unless further restrictions are made. The sandbox does not have access to I/O nor functions and variables outside its environment. The only way for the sandbox to communicate with the external world is by affecting its environment (e.g. getting and setting variables and calling functions in that environment), assuming there is code outside the sandbox that also has access to those variables and functions.
The following is a list of Lua 5.1 variables with descriptions of how safe they for use in sandbox environments. Note that whether a variable is safe or not may depend on the security requirements of your particular application and your Lua state. No warranty is given that the following listing is complete or correct, but it is only a guideline. To make a sandbox you should start with an empty environment and pull in only functions you know for certain to be safe [1] (i.e. a whitelist not a blacklist). You should not rely on the manual providing a complete list of functions (e.g. HiddenFeatures).
assert - SAFE
collectgarbage - UNSAFE - can globally and adversely affect garbage collection
dofile - UNSAFE - The may read arbitrary files on the file system. It can also read standard input. The code is run under the global environment, not the sandbox, so this can be used to break out of the sandbox. Related discussion: DofileNamespaceProposal. Also unsafe if file is compiled bytecodes (see load).
error - SAFE
_G - UNSAFE - by default this contains the global environment. You may, however, want to set this variable to contain the environment of the sandbox.
getfenv - UNSAFE - this can locate an environment outside of the sandbox, thereby breaking out of the sandbox. LuaList:2007-11/msg00202.html
getmetatable - UNSAFE - Note that getmetatable"" returns the metatable of strings. Modification of the contents of that metatable can break code outside the sandbox that relies on this string behavior. Similar cases may exist unless objects are protected appropriately via __metatable. Ideally __metatable should be immutable.
ipairs -- SAFE
load - UNSAFE. The function returned has the global environment, thereby breaking out of the sandbox. More seriously, is dangerous if loading bytecode rather than Lua source: LuaList:2010-08/msg00487.html .
loadfile - UNSAFE. See load and dofile
loadstring -- UNSAFE. See load. Even this:
local oldloadstring = loadstring local function safeloadstring(s, chunkname) local f, message = oldloadstring(s, chunkname) if not f then return f, message end setfenv(f, getfenv(2)) return f end
pcall(safeloadstring, some_script) will load some_script in global environment. --SergeyRozhenko
next - SAFE
pairs - SAFE
pcall - SAFE
print - SAFE (assuming output to stdout is ok)
rawequal - UNSAFE (potentially?) - bypasses metatables
rawget - UNSAFE - bypasses metatables
rawset - UNSAFE - bypasses metatables
select - SAFE
setfenv - UNSAFE - can modify environments of functions that are up the call-chain and outside the sandbox
setmetatable - UNSAFE - see getmetatable
tonumber - SAFE
tostring - SAFE
type - SAFE
unpack - SAFE
_VERSION - SAFE
xpcall - SAFE
coroutine - UNSAFE - modifying this table could affect code outside the sandbox
coroutine.create - SAFE
coroutine.resume - SAFE
coroutine.running - SAFE
coroutine.status - SAFE
coroutine.wrap - SAFE
coroutine.yield - SAFE (probably) - assuming caller handles this
module - UNSAFE - for example, modifies globals (e..g package.loaded) and provides access to environments outside the sandbox.
require - UNSAFE - modifies globals (e.g. package.loaded), provides access to environments outside the sandbox, and accesses the file system.
package - UNSAFE - modifying this table could affect code outside the sandbox
package.* - UNSAFE - affects module loading outside the sandbox
package.loaded - UNSAFE - provides access to modules loaded outside the sandbox
package.loaders - UNSAFE - provides access to loading modules outside the sandbox
package.loadlib - UNSAFE - loads arbitrary executable code that runs outside of Lua
package.path/package.cpath - UNSAFE (effectively) since this is probably useful only for UNSAFE functions. In itself, it is probably SAFE, for reading that is.
package.preload - UNSAFE (probably) - may allow loading modules outside the sandbox
package.seeall - UNSAFE - provides access to the global environment
string - UNSAFE - modifying this table could affect code outside the sandbox
string.byte - SAFE
string.char - SAFE
string.dump - UNSAFE (potentially) - allows seeing implementation of functions.
string.find - SAFE
string.format - SAFE
string.gmatch - SAFE
string.gsub - SAFE
string.len - SAFE
string.lower - SAFE
string.match - SAFE
string.rep - SAFE
string.reverse - SAFE
string.sub - SAFE
string.upper - SAFE
table - UNSAFE - modifying this table could affect code outside the sandbox
table.insert - SAFE
table.maxn - SAFE
table.remove - SAFE
table.sort - SAFE
math - UNSAFE - modifying this table could affect code outside the sandbox
math.abs - SAFE
math.acos - SAFE
math.asin - SAFE
math.atan - SAFE
math.atan2 - SAFE
math.ceil - SAFE
math.cos - SAFE
math.cosh - SAFE
math.deg - SAFE
math.exp - SAFE
math.floor - SAFE
math.fmod - SAFE
math.frexp - SAFE
math.huge - SAFE
math.ldexp - SAFE
math.log - SAFE
math.log10 - SAFE
math.max - SAFE
math.min - SAFE
math.modf - SAFE
math.pi - SAFE
math.pow - SAFE
math.rad - SAFE
math.random - SAFE (mostly) - but note that returned numbers are pseudorandom, and calls to this function affect subsequent calls. This may have statistical implications.
math.randomseed - UNSAFE (maybe) - see math.random
math.sin - SAFE
math.sinh - SAFE
math.sqrt - SAFE
math.tan - SAFE
math.tanh - SAFE
io - UNSAFE - modifying this table could affect code outside the sandbox
io.* - These can be UNSAFE as they provide access to the file system. Note also that io.close on standard file handles (e.g. io.stdin) may be unsafe and could cause a crash.
io.read - SAFE (probably)
io.write - SAFE (probably) - note: potentially could consume all disk space, thereby bringing down a system
io.flush - SAFE (probably)
io.type - SAFE
os - UNSAFE - modifying this table could affect code outside the sandbox
os.clock - SAFE
os.date - UNSAFE - This can crash on some platforms (undocumented). For example, os.date'%v'. It is reported that this will be fixed in 5.2 or 5.1.3.
os.difftime - SAFE
os.execute - UNSAFE - calls external programs
os.exit - UNSAFE - terminates program
os.getenv - UNSAFE (potentially) - depending on what environment variables contain
os.remove - UNSAFE - modifies file system
os.rename - UNSAFE - modifies file system
os.setlocale - UNSAFE - modifies global locale, affecting code outside the sandbox
os.time - SAFE
os.tmpname - UNSAFE (maybe) - only in that it provides some information on the structure of the file system
debug - UNSAFE - modifying this table could affect code outside the sandbox
debug.* - UNSAFE - functions here can break out of the sandbox and access variables outside the sandbox. Note warnings in the Lua Reference Manual concerning debug.
newproxy - UNSAFE (potentially) - This is an undocumented function (HiddenFeatures), so it does not have a specified interface that you can rely on. newproxy(nil) and newproxy(true) are probably safe, though fairly useless if getmetatable is disabled, at least for the proxy. newproxy(o) where o is another proxy object will assign the metatable of o to the new proxy, so there are potential side-effects on o or the metatable of o for any exposed proxy o.
Anonymous: Attacks to consider: