First and foremost execute untrusted code in sandboxed environment only – as it was said by other posters. Except for loading bytecode chunks, Lua allows all other sandboxing issues to be covered. (And bytecode chunk problems get fixed promptly as discovered.)
See Lua Live Demo for an example of sandboxing. Sources are available here.
Your specific problem with metatables is solved by setting a __metatable
field:
If you set a __metatable
field in the metatable,
getmetatable
will return the value of this field,
whereas setmetatable
will raise an error.
– Roberto Ierusalimschy, Programming in Lua 1st edition,
13.3 - Library-Defined Metamethods
For example:
> mt = { __metatable = true }
> t = {}
> setmetatable(t, mt)
> setmetatable(t, mt)
stdin:1: cannot change a protected metatable
stack traceback:
[C]: in function 'setmetatable'
stdin:1: in main chunk
[C]: ?
So, all you have to do is:
getmetatable("").__metatable = true