lua-users home
lua-l archive

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



On 22-Feb-07, at 10:39 PM, Mildred wrote:


I just think it is the same problem with function environments. If lua
bytecode can access function environments, then it have access to
string.gsub environment that is the global environemnt.
That's even worse. Direct access to dangerous functions.

has the bytecode access to those metadata (metatable and environment) ?
if so, is there any way to secure a sandbox ?

There are no opcodes to access metatables and environments. Furthermore, bytecode is verified during the load process. So it ought to be as safe as any Lua program.

Can a Lua program get at metatables (and environments)? A simple test would demonstrate:

Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
> =string
table: 0x806a040
> =getmetatable("")
table: 0x806a420
> return getmetatable("").__index
table: 0x806a040
> -- So the string metatable is available, and the string table is available
> -- via its __index key. Let's lock the metatable:
> getmetatable("").__metatable = false
> =getmetatable("")
false
> -- no more access
> setmetatable("", {})
stdin:1: bad argument #1 to 'setmetatable' (table expected, got string)
stack traceback:
        [C]: in function 'setmetatable'
        stdin:1: in main chunk
        [C]: ?
> -- nope
> -- now, let's get rid of the string table
> string = nil
> =string.sub("foo", 3)
stdin:1: attempt to index global 'string' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
> =("foo"):sub(3)
o

---------------

Does that mean that sandboxing is possible? Yes, but it's tricky.
The above certainly protected the string library, but what about
the math library? In general, you need to create sandboxed versions
of all the library tables you're going to use.

You can certainly change the global environment so that Lua code
can't get at it, but it's probably better to not put anything
important in the global environment at all. The more difficult
issue is require(), which will provide the original library table:

> -- Oops, it's still there even though I deleted it from _G
> =require"string"
table: 0x806a040
> =string
nil
> =package.loaded.string
table: 0x806a040
> -- OK, let's get rid of it from there
> package.loaded.string = {}
> =require"string"
table: 0x8071700